Load ht->ht_Tracks into tune->struct track trk[]. Seems I got it working for lft...
[pineappletracker.git] / gui.c
blob215b473d54b53f9b827c0dc987b22e7425e17b9e
1 /* vi:set ts=8 sts=8 sw=8 noexpandtab: */
3 /* welcome to gui.c, enjoy your stay 8-) */
5 #include "pineapple.h"
6 #include "filetypes.h"
7 #include "gui.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
13 #include <curses.h>
14 #include <unistd.h>
15 #include <ctype.h>
17 #ifndef WINDOWS
18 #include <err.h>
19 #endif
22 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
23 \\\ local vars .\
24 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
25 char *dispmesg = "";
27 static char *notenames[] = {"C-", "C#", "D-", "D#", "E-", "F-", "F#",
28 "G-", "G#", "A-", "A#", "H-"};
30 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
31 \\\ local functions .\
32 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
33 int _char2int(char ch);
34 void _display(void);
36 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
37 \\\ end local declarations .\
38 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
40 char cmdstr[500] = "";
42 int disptick = 0;
43 int currmode = PM_NORMAL;
44 int octave = 4;
45 int songlen = 1;
46 int tracklen = TRACKLEN;
47 int currtrack = 1;
48 int currinstr = 1;
49 int currtab = 0;
50 int saved = 1;
52 int step = 1;
54 int cmdrepeat = 0;
55 int cmdrepeatnum = 1;
56 int lastrepeat = 1;
58 // 0 is like a blank command
59 char *validcmds = "0dfi@smtvw~+=*";
61 /*char *keymap[2] = {
62 ";oqejkixdbhmwnvsz",
63 "'2,3.p5y6f7gc9r0l/="
64 };*/
66 char *keymap[2] = {
67 "zsxdcvgbhnjm,l.;/",
68 "q2w3er5t6y7ui9o0p"
71 /* hexinc and hexdec wrap around */
72 int hexinc(int x){
73 return (x >= 0 && x <= 14)? x+1 : 0;
75 int hexdec(int x){
76 return (x >= 1 && x <= 15)? x-1 : 15;
79 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
80 \\\ < int _char2int(char) > .|
81 /// Draws the instrument editor. .\
82 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
83 int _char2int(char ch){
84 if(isdigit(ch)){
85 return (int)ch - '0';
87 return -1;
90 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
91 \\\ < int freqkey(int) > .|
92 /// Calculates the frequency of key c. .\
93 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
94 int freqkey(int c){
95 char *s;
96 int f = -1;
98 if(c == '-' || c == KEY_DC) return 0;
99 if(c > 0 && c < 256){
100 s = strchr(keymap[0], c);
101 if(s){
102 f = (s - (keymap[0])) + octave * 12 + 1;
103 }else{
104 s = strchr(keymap[1], c);
105 if(s){
106 f = (s - (keymap[1])) + octave * 12 + 12 + 1;
110 if(f > 12 * 9 + 1) return -1;
111 return f;
114 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
115 \\\ < void initsonglines() > .|
116 /// . .\
117 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
118 void initsonglines(void){
119 for(int i=0; i < songlen; i++){
120 memmove(&song[i + 0], &song[i + 1], sizeof(struct songline) * (songlen - i - 1));
121 if(i < 4){
122 song[0].track[i] = 0x00;
123 song[0].transp[i] = 0x00;
126 songlen = 1;
129 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
130 \\\ < void inittracks() > .\
131 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
132 void inittracks(void){
133 for(int i=0; i < 256; i++){
134 for(int j=0; j < TRACKLEN; j++){
135 track[i].line[j].note = 0x00;
136 track[i].line[j].instr = 0x00;
137 for(int k=0; k < 2; k++){
138 track[i].line[j].cmd[k] = 0x0000;
139 track[i].line[j].param[k] = 0x0000;
145 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
146 \\\ < void initinstrs() > .\
147 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
148 void initinstrs(void){
149 for(int i=1; i < 256; i++){
150 instrument[i].length = 1;
151 instrument[i].line[0].cmd = '0';
152 instrument[i].line[0].param = 0;
156 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
157 \\\ < void readsong(int,int,u8) > .\
158 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
159 void readsong(int pos, int ch, u8 *dest){
160 dest[0] = song[pos].track[ch];
161 dest[1] = song[pos].transp[ch];
164 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
165 \\\ < void readtrack(int,int,trackline) > .\
166 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
167 void readtrack(int num, int pos, struct trackline *tl){
168 tl->note = track[num].line[pos].note;
169 tl->instr = track[num].line[pos].instr;
170 tl->cmd[0] = track[num].line[pos].cmd[0];
171 tl->cmd[1] = track[num].line[pos].cmd[1];
172 tl->param[0] = track[num].line[pos].param[0];
173 tl->param[1] = track[num].line[pos].param[1];
176 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
177 \\\ < void readinstr(int,int,u8) > .\
178 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
179 void readinstr(int num, int pos, u8 *il){
180 if(pos >= instrument[num].length){
181 il[0] = 0;
182 il[1] = 0;
183 }else{
184 il[0] = instrument[num].line[pos].cmd;
185 il[1] = instrument[num].line[pos].param;
189 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
190 \\\ < void exitgui() > .|
191 /// Exits the gui. .\
192 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
193 void exitgui(){
194 endwin();
197 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
198 \\\ < void initgui() > .|
199 /// Initializes the gui. .\
200 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
201 void initgui(){
202 initscr();
204 //if(setlocale(LC_CTYPE,"en_US.utf8") != NULL){
205 // setdisplay("UTF-8 enabled!");
208 // don't send newline on Enter key, and don't echo chars to the screen.
209 nonl();
210 noecho();
212 // make sure behaviour for special keys like ^H isn't overridden
213 keypad(stdscr, FALSE);
215 nodelay(stdscr, TRUE);
217 //initinstrs();
219 atexit(exitgui);
222 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
223 \\\ < void handleinput() > .|
224 /// Main input loop. .\
225 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
226 void handleinput(void){
227 int c;
229 //if(currmode == PM_NORMAL){
230 if((c = getch()) != ERR){
232 // Repeat
233 if(isdigit(c)){
234 if(!cmdrepeat){
235 cmdrepeat = 1;
236 cmdrepeatnum = _char2int(c);
237 }else{
238 cmdrepeatnum = (cmdrepeatnum*10) + _char2int(c);
240 }else{
241 normalmode(c);
246 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
247 \\\ < char nextchar() > .|
248 /// Wait for the next keyboard char and return it. .\
249 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
250 char nextchar(void){
251 char ch;
252 ch = getch();
253 while (ch == ERR){
254 ch = getch();
255 if(ch != ERR )
256 return ch;
258 return ch;
261 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
262 \\\ < void setdisplay(char*) > .|
263 /// Sets a message to be popped up for a while. .\
264 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
265 void setdisplay(char *str){
266 disptick = 350;
267 dispmesg = str;
270 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
271 \\\ < void drawgui() > .|
272 /// Draw all text and graphix to the screen. .\
273 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
274 void drawgui(){
275 char buf[1024];
276 int lines = LINES;
277 int songcols[] = {0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22};
278 int trackcols[] = {0, 2, 4, 5, 7, 8, 9, 11, 12, 13};
279 int instrcols[] = {0, 2, 3};
280 u8 tempo;
282 erase();
283 attrset(A_UNDERLINE);
284 mvaddstr(0, 0, "PINEAPPLEtRACKER");
285 attrset(A_NORMAL);
287 // display track num
288 mvaddch(0, 31, ACS_ULCORNER);
289 snprintf(buf, sizeof(buf), "%02x{}", currtrack);
290 mvaddstr(0, 32, buf);
291 drawtracked(29, 1, lines - 2);
293 // display instrument num
294 mvaddch(0, 51, ACS_ULCORNER);
295 snprintf(buf, sizeof(buf), "%02x[]", currinstr);
296 mvaddstr(0, 52, buf);
297 drawinstred(49, 1, lines - 2);
299 mvaddstr(1, 0, "Song");
300 drawsonged(0, 1, lines - 2);
302 // just a wild guess here..
303 tempo = callbacktime * (-1) + 300;
304 // display tempo
305 mvaddch(0, 17, ACS_DEGREE);
306 snprintf(buf, sizeof(buf), "%d()", tempo);
307 mvaddstr(0, 18, buf);
309 // display octave
310 mvaddch(0, 24, ACS_PI);
311 snprintf(buf, sizeof(buf), "%d<>", octave);
312 mvaddstr(0, 25, buf);
314 // display step amount
315 mvaddstr(0, 60, "step -=");
316 snprintf(buf, sizeof(buf), "%0x", step);
317 mvaddstr(0, 68, buf);
319 // display comment
320 mvaddstr(2, 60, "comment:");
321 snprintf(buf, sizeof(buf), "%s", comment);
322 mvaddstr(3, 60, buf);
324 if(currmode == PM_NORMAL){
325 mvaddstr(getmaxy(stdscr)-1, 0, filename);
326 if(!saved && currmode != PM_INSERT){
327 addstr(" [+]");
328 infinitemsg = NULL;
332 if(disptick > 0){
333 _display();
334 disptick--;
337 if(currmode == PM_INSERT){
338 infinitemsg = NULL;
340 move(getmaxy(stdscr)-1,0);
341 clrtoeol();
342 mvaddstr(getmaxy(stdscr)-1, 0, "-- INSERT --");
343 }else if(currmode == PM_VISUAL){
344 infinitemsg = NULL;
346 move(getmaxy(stdscr)-1,0);
347 clrtoeol();
348 mvaddstr(getmaxy(stdscr)-1, 0, "-- VISUAL --");
349 }else if(currmode == PM_VISUALLINE){
350 infinitemsg = NULL;
352 move(getmaxy(stdscr)-1,0);
353 clrtoeol();
354 mvaddstr(getmaxy(stdscr)-1, 0, "-- VISUAL LINE --");
355 }else if(currmode == PM_JAMMER){
356 infinitemsg = NULL;
358 move(getmaxy(stdscr)-1,0);
359 clrtoeol();
360 mvaddstr(getmaxy(stdscr)-1, 0, "-- JAMMER --");
361 }else if(currmode == PM_CMDLINE){
362 infinitemsg = NULL;
364 move(getmaxy(stdscr)-1,0);
365 clrtoeol();
366 mvaddstr(getmaxy(stdscr) - 1, 0, cmdstr);
367 }else if(infinitemsg != NULL){
368 move(getmaxy(stdscr)-1,0);
369 clrtoeol();
370 mvaddstr(getmaxy(stdscr) - 1, 0, infinitemsg);
373 switch(currtab){
374 case 0:
375 move(1 + songy - songoffs, 0 + 4 + songcols[songx]);
376 break;
377 case 1:
378 move(1 + tracky - trackoffs, 29 + 4 + trackcols[trackx]);
379 break;
380 case 2:
381 move(1 + instry - instroffs, 49 + 4 + instrcols[instrx]);
382 break;
385 refresh();
387 if(disptick > 0){
388 disptick--;
392 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
393 \\\ < void *spin_input(void *) > .|
394 /// Pass this function to a thread to get the next key without blocking the .\
395 \\\ the gui. .\
396 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
397 /*void *spin_input(void *tid){
398 for(;;){
399 handleinput();
400 msleep(500);
404 void *spin_gui(void *tid){
405 for(;;){
406 drawgui();
407 msleep(50000);
411 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
412 \\\ < void eventloop() > .|
413 /// Main event loop .\
414 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
415 void eventloop(void){
416 #ifndef WINDOWS
417 ESCDELAY = 50;
418 #endif
419 for(;;){
420 drawgui();
421 handleinput();
425 //--------------------------------------------------------------------------\\
426 // this is when i tried to make separate threads for the screen and the
427 // input
428 //--------------------------------------------------------------------------//
429 //TODO: figure out a method where we don't have to use usleep()... the
430 // screen also jitters sometimes
431 /*void eventloop(void){
432 int rc;
433 pthread_t inputthread;
434 pthread_t guithread;
435 pthread_attr_t attr;
437 // make it detached ... we won't need to join it
438 pthread_attr_init(&attr);
439 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
441 rc = pthread_create(&inputthread,&attr,spin_input,(void *)0);
442 if(rc)
443 setdisplay("Uh oh!!! thread please");
445 rc = pthread_create(&guithread,&attr,spin_gui,(void *)0);
447 #ifndef WINDOWS
448 // don't treat the escape key like a meta key
449 ESCDELAY = 50;
450 #endif
452 for(;;){
453 msleep(1000);
457 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
458 \\\ Internal functions .\
459 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
461 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
462 \\\ < void _display() > .|
463 /// Display dispmesg in the center of the screen. .\
464 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
465 void _display(void){
466 int cx = (getmaxx(stdscr)/2)-(strlen(dispmesg)/2)-1;
467 int cy = getmaxy(stdscr)/2;
469 mvaddch(cy-1, cx, ACS_ULCORNER);
470 for(int i=cx+1; i<cx+strlen(dispmesg)+1; i++)
471 mvaddch(cy-1, i, ACS_HLINE);
472 mvaddch(cy-1, cx+strlen(dispmesg)+1, ACS_URCORNER);
474 mvaddch(cy, cx, ACS_VLINE);
475 mvaddstr(cy, cx+1, dispmesg);
476 mvaddch(cy, cx+strlen(dispmesg)+1, ACS_VLINE);
478 mvaddch(cy+1, cx, ACS_LLCORNER);
479 for(int i=cx+1; i<cx+strlen(dispmesg)+1; i++)
480 mvaddch(cy+1, i, ACS_HLINE);
481 mvaddch(cy+1, cx+strlen(dispmesg)+1, ACS_LRCORNER);
484 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
485 \\\ < void drawsonged(int,int,int) > .|
486 /// Draws the song editor. .\
487 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
488 void drawsonged(int x, int y, int height){
489 int i, j;
490 char buf[1024];
491 //NODE *match;
493 if(songy < songoffs) songoffs = songy;
494 if(songy >= songoffs + height) songoffs = songy - height + 1;
496 for(i = 0; i < tune->songlen; i++){
497 if(i >= songoffs && i - songoffs < height){
498 move(y + i - songoffs, x + 0);
499 if(i == songy) attrset(A_BOLD);
501 snprintf(buf, sizeof(buf), "%02x", i);
503 if(i == 0){ addch(ACS_ULCORNER); }
504 else if(i == tune->songlen-1){ addch(ACS_LLCORNER); }
505 else if(i%4 == 0){ addch(ACS_LTEE); }
506 else if(i < tune->songlen-1){ addch(ACS_VLINE); }
507 addch(' ');
509 // should this line be highlighted?
510 //if( (match = list_contains(highlightlines, findu8, &i)) ){
511 if( currtab == 0 && currmode == PM_VISUALLINE &&
512 ((i <= highlight_firstline && i >= highlight_lastline)
513 || (i >= highlight_firstline && i <= highlight_lastline)) ){
514 attrset(A_REVERSE);
517 addstr(buf);
518 for(j = 0; j < 4; j++){
519 snprintf(buf, sizeof(buf), "%02x:%02x", tune->sng[i].track[j], tune->sng[i].transp[j]);
520 addstr(buf);
521 if(j != 3) addch(' ');
523 if(playsong && tune->songpos == (i + 1)){
524 attrset(A_STANDOUT);
525 addch('*');
527 attrset(A_NORMAL);
532 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
533 \\\ < void drawtracked(int,int,int) > .|
534 /// Draws the track editor. .\
535 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
536 void drawtracked(int x, int y, int height){
537 u8 i, j;
538 char buf[1024];
540 if(tracky < trackoffs) trackoffs = tracky;
541 if(tracky >= trackoffs + height) trackoffs = tracky - height + 1;
543 for(i = 0; i < tune->tracklen; i++){
544 if(i >= trackoffs && i - trackoffs < height){
545 move(y + i - trackoffs, x + 0);
546 if(i == tracky) attrset(A_BOLD);
548 snprintf(buf, sizeof(buf), "%02x", i);
549 addstr(buf);
551 if(i == 0){ addch(ACS_LLCORNER); }
552 else if(i == 1){ addch(ACS_ULCORNER); }
553 else if(i == tune->tracklen-1){ addch(ACS_LLCORNER); }
554 else if(i%4 == 0){ addch(ACS_LTEE); }
555 else if(i < tune->tracklen-1){ addch(ACS_VLINE); }
556 addch(' ');
558 // should this line be highlighted?
559 //if( (match = list_contains(highlightlines, findu8, &i)) ){
560 if(currtab == 1 && currmode == PM_VISUALLINE
561 && ((i <= highlight_firstline && i >= highlight_lastline)
562 || (i >= highlight_firstline && i <= highlight_lastline)) ){
563 attrset(A_REVERSE);
566 if (currtab == 1 && currmode == PM_VISUAL)
567 attrset(A_REVERSE);
569 if(tune->trk[currtrack].line[i].note){
570 snprintf(buf, sizeof(buf), "%s%d",
571 notenames[(tune->trk[currtrack].line[i].note - 1) % 12],
572 (tune->trk[currtrack].line[i].note - 1) / 12);
573 }else{
574 snprintf(buf, sizeof(buf), "---");
576 addstr(buf);
577 snprintf(buf, sizeof(buf), " %02x", tune->trk[currtrack].line[i].instr);
578 addstr(buf);
579 for(j = 0; j < 2; j++){
580 if(tune->trk[currtrack].line[i].cmd[j]){
581 snprintf(buf, sizeof(buf), " %c%02x",
582 tune->trk[currtrack].line[i].cmd[j],
583 tune->trk[currtrack].line[i].param[j]);
584 }else{
585 snprintf(buf, sizeof(buf), " ...");
587 addstr(buf);
589 if(playtrack && ((i + 1) % tune->tracklen) == tune->trackpos){
590 attrset(A_STANDOUT);
591 addch('*');
593 attrset(A_NORMAL);
598 //\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\/\\
599 \\\ < void drawinstred(int,int,int) > .|
600 /// Draws the instrument editor. .\
601 \\/\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\//
602 void drawinstred(int x, int y, int height){
603 u8 i;
604 char buf[1024];
606 if(instry >= instrument[currinstr].length) instry = instrument[currinstr].length - 1;
608 if(instry < instroffs) instroffs = instry;
609 if(instry >= instroffs + height) instroffs = instry - height + 1;
611 for(i = 0; i < instrument[currinstr].length; i++){
612 if(i >= instroffs && i - instroffs < height){
613 move(y + i - instroffs, x + 0);
614 if(i == instry) attrset(A_BOLD);
616 snprintf(buf, sizeof(buf), "%02x", i);
617 addstr(buf);
619 if(i == 0){ addch(ACS_LLCORNER); }
620 else if(i == 1){ addch(ACS_ULCORNER); }
621 else if(i == instrument[currinstr].length-1){ addch(ACS_LLCORNER); }
622 else if(i < instrument[currinstr].length-1){ addch(ACS_VLINE); }
623 addch(' ');
625 // should this line be highlighted?
626 //if( (match = list_contains(highlightlines, findu8, &i)) ){
627 if( currtab == 2 && currmode == PM_VISUALLINE &&
628 ((i <= highlight_firstline && i >= highlight_lastline)
629 || (i >= highlight_firstline && i <= highlight_lastline)) ){
630 attrset(A_REVERSE);
633 snprintf(buf, sizeof(buf), "%c ", instrument[currinstr].line[i].cmd);
634 addstr(buf);
635 if(instrument[currinstr].line[i].cmd == '+' || instrument[currinstr].line[i].cmd == '='){
636 if(instrument[currinstr].line[i].param){
637 snprintf(buf, sizeof(buf), "%s%d",
638 notenames[(instrument[currinstr].line[i].param - 1) % 12],
639 (instrument[currinstr].line[i].param - 1) / 12);
640 }else{
641 snprintf(buf, sizeof(buf), "---");
643 }else{
644 snprintf(buf, sizeof(buf), "%02x", instrument[currinstr].line[i].param);
646 addstr(buf);
647 attrset(A_NORMAL);