1 /* 2 * Schism Tracker - a cross-platform Impulse Tracker clone 3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com> 4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org> 5 * copyright (c) 2009 Storlek & Mrs. Brisby 6 * copyright (c) 2010-2012 Storlek 7 * URL: http://schismtracker.org/ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #include "headers.h" 25 26 #include "it.h" 27 #include "song.h" 28 #include "pattern-view.h" 29 30 /* this stuff's ugly */ 31 32 33 /* --------------------------------------------------------------------- */ 34 /* pattern edit mask indicators */ 35 36 /* 37 atnote (1) cursor_pos == 0 38 over (2) cursor_pos == pos 39 masked (4) mask & MASK_whatever 40 */ 41 static const char mask_chars[] = { 42 143, // 0 43 143, // atnote 44 169, // over 45 169, // over && atnote 46 170, // masked 47 169, // masked && atnote 48 171, // masked && over 49 171, // masked && over && atnote 50 }; 51 #define MASK_CHAR(field, pos, pos2) \ main(void)52 mask_chars [ \ 53 ((cursor_pos == 0) ? 1 : 0) | \ 54 ((cursor_pos == pos) ? 2 : 0) | \ 55 ((pos2 && cursor_pos == pos2) ? 2 : 0) | \ 56 ((mask & field) ? 4 : 0) ] 57 58 /* --------------------------------------------------------------------- */ 59 /* 13-column track view */ 60 61 void draw_channel_header_13(int chan, int x, int y, int fg) 62 { 63 char buf[16]; 64 sprintf(buf, " Channel %02d ", chan); 65 draw_text(buf, x, y, fg, 1); 66 } 67 68 void draw_note_13(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) 69 { 70 int cursor_pos_map[9] = { 0, 2, 4, 5, 7, 8, 10, 11, 12 }; 71 char note_text[16], note_buf[4], vol_buf[4]; 72 char instbuf[4]; 73 74 get_note_string(note->note, note_buf); 75 get_volume_string(note->volparam, note->voleffect, vol_buf); 76 77 /* come to think of it, maybe the instrument text should be 78 * created the same way as the volume. */ 79 if (note->instrument) 80 num99tostr(note->instrument, instbuf); 81 else 82 strcpy(instbuf, "\xad\xad"); 83 84 snprintf(note_text, 16, "%s %s %s %c%02X", 85 note_buf, instbuf, vol_buf, 86 get_effect_char(note->effect), note->param); 87 88 if (show_default_volumes && note->voleffect == VOLFX_NONE 89 && note->instrument > 0 && NOTE_IS_NOTE(note->note)) { 90 song_sample_t *smp = song_is_instrument_mode() 91 ? csf_translate_keyboard(current_song, song_get_instrument(note->instrument), 92 note->note, NULL) 93 : song_get_sample(note->instrument); 94 if (smp) { 95 /* Modplug-specific hack: volume bit shift */ 96 int n = smp->volume >> 2; 97 note_text[6] = 0xbf; 98 note_text[7] = '0' + n / 10 % 10; 99 note_text[8] = '0' + n / 1 % 10; 100 note_text[9] = 0xc0; 101 } 102 } 103 104 draw_text(note_text, x, y, fg, bg); 105 106 /* lazy coding here: the panning is written twice, or if the 107 * cursor's on it, *three* times. */ 108 if (note->voleffect == VOLFX_PANNING) 109 draw_text(vol_buf, x + 7, y, 2, bg); 110 111 if (cursor_pos == 9) { 112 draw_text(note_text + 10, x + 10, y, 0, 3); 113 } else if (cursor_pos >= 0) { 114 cursor_pos = cursor_pos_map[cursor_pos]; 115 draw_char(note_text[cursor_pos], x + cursor_pos, y, 0, 3); 116 } 117 } 118 119 void draw_mask_13(int x, int y, int mask, int cursor_pos, int fg, int bg) 120 { 121 char buf[] = { 122 MASK_CHAR(MASK_NOTE, 0, 0), 123 MASK_CHAR(MASK_NOTE, 0, 0), 124 MASK_CHAR(MASK_NOTE, 0, 1), 125 143, 126 MASK_CHAR(MASK_INSTRUMENT, 2, 0), 127 MASK_CHAR(MASK_INSTRUMENT, 3, 0), 128 143, 129 MASK_CHAR(MASK_VOLUME, 4, 0), 130 MASK_CHAR(MASK_VOLUME, 5, 0), 131 143, 132 MASK_CHAR(MASK_EFFECT, 6, 0), 133 MASK_CHAR(MASK_EFFECT, 7, 0), 134 MASK_CHAR(MASK_EFFECT, 8, 0), 135 0, 136 }; 137 138 draw_text(buf, x, y, fg, bg); 139 } 140 141 /* --------------------------------------------------------------------- */ 142 /* 10-column track view */ 143 144 void draw_channel_header_10(int chan, int x, int y, int fg) 145 { 146 char buf[16]; 147 sprintf(buf, "Channel %02d", chan); 148 draw_text(buf, x, y, fg, 1); 149 } 150 151 void draw_note_10(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) 152 { 153 uint8_t c; 154 char note_buf[4], ins_buf[3], vol_buf[3], effect_buf[4]; 155 156 get_note_string(note->note, note_buf); 157 if (note->instrument) { 158 num99tostr(note->instrument, ins_buf); 159 } else { 160 ins_buf[0] = ins_buf[1] = 173; 161 ins_buf[2] = 0; 162 } 163 get_volume_string(note->volparam, note->voleffect, vol_buf); 164 sprintf(effect_buf, "%c%02X", get_effect_char(note->effect), 165 note->param); 166 167 draw_text(note_buf, x, y, 6, bg); 168 draw_text(ins_buf, x + 3, y, note->instrument ? 10 : 2, bg); 169 draw_text(vol_buf, x + 5, y, ((note->voleffect == VOLFX_PANNING) ? 2 : 6), bg); 170 draw_text(effect_buf, x + 7, y, 2, bg); 171 172 if (cursor_pos < 0) 173 return; 174 if (cursor_pos > 0) 175 cursor_pos++; 176 if (cursor_pos == 10) { 177 draw_text(effect_buf, x + 7, y, 0, 3); 178 } else { 179 switch (cursor_pos) { 180 case 0: c = note_buf[0]; break; 181 case 2: c = note_buf[2]; break; 182 case 3: c = ins_buf[0]; break; 183 case 4: c = ins_buf[1]; break; 184 case 5: c = vol_buf[0]; break; 185 case 6: c = vol_buf[1]; break; 186 default: /* 7->9 */ 187 c = effect_buf[cursor_pos - 7]; 188 break; 189 } 190 draw_char(c, x + cursor_pos, y, 0, 3); 191 } 192 } 193 194 void draw_mask_10(int x, int y, int mask, int cursor_pos, int fg, int bg) 195 { 196 char buf[] = { 197 MASK_CHAR(MASK_NOTE, 0, 0), 198 MASK_CHAR(MASK_NOTE, 0, 0), 199 MASK_CHAR(MASK_NOTE, 0, 1), 200 MASK_CHAR(MASK_INSTRUMENT, 2, 0), 201 MASK_CHAR(MASK_INSTRUMENT, 3, 0), 202 MASK_CHAR(MASK_VOLUME, 4, 0), 203 MASK_CHAR(MASK_VOLUME, 5, 0), 204 MASK_CHAR(MASK_EFFECT, 6, 0), 205 MASK_CHAR(MASK_EFFECT, 7, 0), 206 MASK_CHAR(MASK_EFFECT, 8, 0), 207 0, 208 }; 209 210 draw_text(buf, x, y, fg, bg); 211 } 212 213 /* --------------------------------------------------------------------- */ 214 /* 8-column track view (no instrument column; no editing) */ 215 216 void draw_channel_header_8(int chan, int x, int y, int fg) 217 { 218 char buf[8]; 219 sprintf(buf, " %02d ", chan); 220 draw_text(buf, x, y, fg, 1); 221 } 222 223 void draw_note_8(int x, int y, const song_note_t *note, UNUSED int cursor_pos, int fg, int bg) 224 { 225 char buf[4]; 226 227 get_note_string(note->note, buf); 228 draw_text(buf, x, y, fg, bg); 229 230 if (note->volparam || note->voleffect) { 231 get_volume_string(note->volparam, note->voleffect, buf); 232 draw_text(buf, x + 3, y, (note->voleffect == VOLFX_PANNING) ? 1 : 2, bg); 233 } else { 234 draw_char(0, x + 3, y, fg, bg); 235 draw_char(0, x + 4, y, fg, bg); 236 } 237 238 snprintf(buf, 4, "%c%02X", get_effect_char(note->effect), note->param); 239 buf[3] = '\0'; 240 draw_text(buf, x + 5, y, fg, bg); 241 } 242 243 /* --------------------------------------------------------------------- */ 244 /* 7-column track view */ 245 246 void draw_channel_header_7(int chan, int x, int y, int fg) 247 { 248 char buf[8]; 249 sprintf(buf, "Chnl %02d", chan); 250 draw_text(buf, x, y, fg, 1); 251 } 252 253 void draw_note_7(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) 254 { 255 char note_buf[4], ins_buf[3], vol_buf[3]; 256 int fg1, bg1, fg2, bg2; 257 258 get_note_string(note->note, note_buf); 259 if (note->instrument) 260 num99tostr(note->instrument, ins_buf); 261 else 262 ins_buf[0] = ins_buf[1] = 173; 263 get_volume_string(note->volparam, note->voleffect, vol_buf); 264 265 /* note & instrument */ 266 draw_text(note_buf, x, y, 6, bg); 267 fg1 = fg2 = (note->instrument ? 10 : 2); 268 bg1 = bg2 = bg; 269 switch (cursor_pos) { 270 case 0: 271 draw_char(note_buf[0], x, y, 0, 3); 272 break; 273 case 1: 274 draw_char(note_buf[2], x + 2, y, 0, 3); 275 break; 276 case 2: 277 fg1 = 0; 278 bg1 = 3; 279 break; 280 case 3: 281 fg2 = 0; 282 bg2 = 3; 283 break; 284 } 285 draw_half_width_chars(ins_buf[0], ins_buf[1], x + 3, y, fg1, bg1, 286 fg2, bg2); 287 288 /* volume */ 289 switch (note->voleffect) { 290 case VOLFX_NONE: 291 fg1 = 6; 292 break; 293 case VOLFX_PANNING: 294 fg1 = 10; 295 break; 296 case VOLFX_TONEPORTAMENTO: 297 case VOLFX_VIBRATOSPEED: 298 case VOLFX_VIBRATODEPTH: 299 fg1 = 6; 300 break; 301 default: 302 fg1 = 12; 303 break; 304 } 305 fg2 = fg1; 306 bg1 = bg2 = bg; 307 308 switch (cursor_pos) { 309 case 4: 310 fg1 = 0; 311 bg1 = 3; 312 break; 313 case 5: 314 fg2 = 0; 315 bg2 = 3; 316 break; 317 } 318 draw_half_width_chars(vol_buf[0], vol_buf[1], x + 4, y, fg1, bg1, fg2, bg2); 319 320 /* effect value */ 321 fg1 = fg2 = 10; 322 bg1 = bg2 = bg; 323 switch (cursor_pos) { 324 case 7: 325 fg1 = 0; 326 bg1 = 3; 327 break; 328 case 8: 329 fg2 = 0; 330 bg2 = 3; 331 break; 332 case 9: 333 fg1 = fg2 = 0; 334 bg1 = bg2 = 3; 335 cursor_pos = 6; // hack 336 break; 337 } 338 draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], 339 hexdigits[note->param & 0xf], 340 x + 6, y, fg1, bg1, fg2, bg2); 341 342 /* effect */ 343 draw_char(get_effect_char(note->effect), x + 5, y, 344 (cursor_pos == 6) ? 0 : 2, (cursor_pos == 6) ? 3 : bg); 345 } 346 347 void draw_mask_7(int x, int y, int mask, int cursor_pos, int fg, int bg) 348 { 349 char buf[] = { 350 MASK_CHAR(MASK_NOTE, 0, 0), 351 MASK_CHAR(MASK_NOTE, 0, 0), 352 MASK_CHAR(MASK_NOTE, 0, 1), 353 MASK_CHAR(MASK_INSTRUMENT, 2, 3), 354 MASK_CHAR(MASK_VOLUME, 4, 5), 355 MASK_CHAR(MASK_EFFECT, 6, 0), 356 MASK_CHAR(MASK_EFFECT, 7, 8), 357 0, 358 }; 359 360 draw_text(buf, x, y, fg, bg); 361 } 362 363 /* --------------------------------------------------------------------- */ 364 /* 3-column track view */ 365 366 void draw_channel_header_3(int chan, int x, int y, int fg) 367 { 368 char buf[4] = { ' ', '0' + chan / 10, '0' + chan % 10, '\0' }; 369 draw_text(buf, x, y, fg, 1); 370 } 371 372 void draw_note_3(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) 373 { 374 char buf[4]; 375 int vfg = 6; 376 377 switch (note->voleffect) { 378 case VOLFX_VOLUME: 379 vfg = 2; 380 break; 381 case VOLFX_PANNING: 382 case VOLFX_NONE: 383 vfg = 1; 384 break; 385 } 386 387 switch (cursor_pos) { 388 case 0: 389 vfg = fg = 0; 390 bg = 3; 391 break; 392 case 1: 393 get_note_string(note->note, buf); 394 draw_text(buf, x, y, 6, bg); 395 draw_char(buf[2], x + 2, y, 0, 3); 396 return; 397 case 2: 398 case 3: 399 cursor_pos -= 1; 400 buf[0] = ' '; 401 if (note->instrument) { 402 num99tostr(note->instrument, buf + 1); 403 } else { 404 buf[1] = buf[2] = 173; 405 buf[3] = 0; 406 } 407 draw_text(buf, x, y, 6, bg); 408 draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); 409 return; 410 case 4: 411 case 5: 412 cursor_pos -= 3; 413 buf[0] = ' '; 414 get_volume_string(note->volparam, note->voleffect, buf + 1); 415 draw_text(buf, x, y, vfg, bg); 416 draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); 417 return; 418 case 6: 419 case 7: 420 case 8: 421 cursor_pos -= 6; 422 sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); 423 draw_text(buf, x, y, 2, bg); 424 draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); 425 return; 426 case 9: 427 sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); 428 draw_text(buf, x, y, 0, 3); 429 return; 430 default: 431 /* bleh */ 432 fg = 6; 433 break; 434 } 435 436 if (note->note) { 437 get_note_string(note->note, buf); 438 draw_text(buf, x, y, fg, bg); 439 } else if (note->instrument) { 440 buf[0] = ' '; 441 num99tostr(note->instrument, buf + 1); 442 draw_text(buf, x, y, fg, bg); 443 } else if (note->voleffect) { 444 buf[0] = ' '; 445 get_volume_string(note->volparam, note->voleffect, buf + 1); 446 draw_text(buf, x, y, vfg, bg); 447 } else if (note->effect || note->param) { 448 if (cursor_pos != 0) 449 fg = 2; 450 sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); 451 draw_text(buf, x, y, fg, bg); 452 } else { 453 buf[0] = buf[1] = buf[2] = 173; 454 buf[3] = 0; 455 draw_text(buf, x, y, fg, bg); 456 } 457 } 458 459 void draw_mask_3(int x, int y, int mask, int cursor_pos, int fg, int bg) 460 { 461 char buf[] = {143, 143, 143, 0}; 462 463 switch (cursor_pos) { 464 case 0: case 1: 465 buf[0] = buf[1] = MASK_CHAR(MASK_NOTE, 0, 0); 466 buf[2] = MASK_CHAR(MASK_NOTE, 0, 1); 467 break; 468 case 2: case 3: 469 buf[1] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); 470 buf[2] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); 471 break; 472 case 4: case 5: 473 buf[1] = MASK_CHAR(MASK_VOLUME, 4, 0); 474 buf[2] = MASK_CHAR(MASK_VOLUME, 5, 0); 475 break; 476 case 6: case 7: case 8: 477 buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); 478 buf[1] = MASK_CHAR(MASK_EFFECT, 7, 0); 479 buf[2] = MASK_CHAR(MASK_EFFECT, 8, 0); 480 break; 481 }; 482 483 draw_text(buf, x, y, fg, bg); 484 } 485 486 /* --------------------------------------------------------------------- */ 487 /* 2-column track view */ 488 489 void draw_channel_header_2(int chan, int x, int y, int fg) 490 { 491 char buf[4] = { '0' + chan / 10, '0' + chan % 10, 0 }; 492 draw_text(buf, x, y, fg, 1); 493 } 494 495 static void draw_effect_2(int x, int y, const song_note_t *note, int cursor_pos, int bg) 496 { 497 int fg = 2, fg1 = 10, fg2 = 10, bg1 = bg, bg2 = bg; 498 499 switch (cursor_pos) { 500 case 0: 501 fg = fg1 = fg2 = 0; 502 break; 503 case 6: 504 fg = 0; 505 bg = 3; 506 break; 507 case 7: 508 fg1 = 0; 509 bg1 = 3; 510 break; 511 case 8: 512 fg2 = 0; 513 bg2 = 3; 514 break; 515 case 9: 516 fg = fg1 = fg2 = 0; 517 bg = bg1 = bg2 = 3; 518 break; 519 } 520 draw_char(get_effect_char(note->effect), x, y, fg, bg); 521 draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], 522 hexdigits[note->param & 0xf], 523 x + 1, y, fg1, bg1, fg2, bg2); 524 } 525 526 void draw_note_2(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) 527 { 528 char buf[4]; 529 int vfg = 6; 530 531 switch (note->voleffect) { 532 case VOLFX_VOLUME: 533 vfg = 2; 534 break; 535 case VOLFX_PANNING: 536 case VOLFX_NONE: 537 vfg = 1; 538 break; 539 } 540 541 switch (cursor_pos) { 542 case 0: 543 vfg = fg = 0; 544 bg = 3; 545 case 1: /* Mini-accidentals on 2-col. view */ 546 get_note_string(note->note, buf); 547 draw_char(buf[0], x, y, fg, bg); 548 // XXX cut-and-paste hackjob programming... this code should only exist in one place 549 switch ((unsigned char) buf[0]) { 550 case '^': 551 case '~': 552 case 0xCD: // note off 553 case 0xAD: // dot (empty) 554 if (cursor_pos == 1) 555 draw_char(buf[1], x + 1, y, 0, 3); 556 else 557 draw_char(buf[1], x + 1, y, fg, bg); 558 break; 559 default: 560 draw_half_width_chars(buf[1], buf[2], x + 1, y, 561 fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); 562 break; 563 } 564 return; 565 /* 566 get_note_string_short(note->note, buf); 567 draw_char(buf[0], x, y, 6, bg); 568 draw_char(buf[1], x + 1, y, 0, 3); 569 return; 570 */ 571 case 2: 572 case 3: 573 cursor_pos -= 2; 574 if (note->instrument) { 575 num99tostr(note->instrument, buf); 576 } else { 577 buf[0] = buf[1] = 173; 578 buf[2] = 0; 579 } 580 draw_text(buf, x, y, 6, bg); 581 draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); 582 return; 583 case 4: 584 case 5: 585 cursor_pos -= 4; 586 get_volume_string(note->volparam, note->voleffect, buf); 587 draw_text(buf, x, y, vfg, bg); 588 draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); 589 return; 590 case 6: 591 case 7: 592 case 8: 593 case 9: 594 draw_effect_2(x, y, note, cursor_pos, bg); 595 return; 596 default: 597 /* bleh */ 598 fg = 6; 599 break; 600 } 601 602 if (note->note) { 603 get_note_string(note->note, buf); 604 draw_char(buf[0], x, y, 6, bg); 605 switch ((unsigned char) buf[0]) { 606 case '^': 607 case '~': 608 case 0xCD: // note off 609 case 0xAD: // dot (empty) 610 if (cursor_pos == 1) 611 draw_char(buf[1], x + 1, y, 0, 3); 612 else 613 draw_char(buf[1], x + 1, y, fg, bg); 614 break; 615 default: 616 draw_half_width_chars(buf[1], buf[2], x + 1, y, 617 fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); 618 break; 619 } 620 /* 621 get_note_string_short(note->note, buf); 622 draw_text(buf, x, y, fg, bg); 623 */ 624 } else if (note->instrument) { 625 num99tostr(note->instrument, buf); 626 draw_text(buf, x, y, fg, bg); 627 } else if (note->voleffect) { 628 get_volume_string(note->volparam, note->voleffect, buf); 629 draw_text(buf, x, y, vfg, bg); 630 } else if (note->effect || note->param) { 631 draw_effect_2(x, y, note, cursor_pos, bg); 632 } else { 633 draw_char(173, x, y, fg, bg); 634 draw_char(173, x + 1, y, fg, bg); 635 } 636 } 637 638 void draw_mask_2(int x, int y, int mask, int cursor_pos, int fg, int bg) 639 { 640 char buf[] = {143, 143, 0}; 641 642 switch (cursor_pos) { 643 case 0: case 1: 644 buf[0] = MASK_CHAR(MASK_NOTE, 0, 0); 645 buf[1] = MASK_CHAR(MASK_NOTE, 0, 1); 646 break; 647 case 2: case 3: 648 buf[0] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); 649 buf[1] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); 650 break; 651 case 4: case 5: 652 buf[0] = MASK_CHAR(MASK_VOLUME, 4, 0); 653 buf[1] = MASK_CHAR(MASK_VOLUME, 5, 0); 654 break; 655 case 6: case 7: case 8: 656 buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); 657 buf[1] = MASK_CHAR(MASK_EFFECT, 7, 8); 658 break; 659 }; 660 661 draw_text(buf, x, y, fg, bg); 662 } 663 664 /* --------------------------------------------------------------------- */ 665 /* 1-column track view... useful to look at, not so much to edit. 666 * (in fact, impulse tracker doesn't edit with this view) */ 667 668 void draw_channel_header_1(int chan, int x, int y, int fg) 669 { 670 draw_half_width_chars('0' + chan / 10, '0' + chan % 10, x, y, fg, 1, fg, 1); 671 } 672 673 static void draw_effect_1(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) 674 { 675 int fg1 = fg, fg2 = fg, bg1 = bg, bg2 = bg; 676 677 switch (cursor_pos) { 678 case 0: 679 break; 680 case 6: 681 fg = 0; 682 bg = 3; 683 break; 684 case 7: 685 fg1 = 0; 686 bg1 = 3; 687 break; 688 case 8: 689 fg2 = 0; 690 bg2 = 3; 691 break; 692 default: 693 fg = 2; 694 } 695 if (cursor_pos == 7 || cursor_pos == 8 || (note->effect == 0 && note->param != 0)) { 696 draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], 697 hexdigits[note-> param & 0xf], 698 x, y, fg1, bg1, fg2, bg2); 699 } else { 700 draw_char(get_effect_char(note->effect), x, y, fg, bg); 701 } 702 } 703 704 void draw_note_1(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) 705 { 706 char buf[4]; 707 708 switch (cursor_pos) { 709 case 0: 710 fg = 0; 711 bg = 3; 712 if (note->note > 0 && note->note <= 120) { 713 get_note_string_short(note->note, buf); 714 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); 715 return; 716 } 717 break; 718 case 1: 719 get_note_string_short(note->note, buf); 720 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); 721 return; 722 case 2: 723 case 3: 724 cursor_pos -= 2; 725 if (note->instrument) 726 num99tostr(note->instrument, buf); 727 else 728 buf[0] = buf[1] = 173; 729 if (cursor_pos == 0) 730 draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); 731 else 732 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); 733 return; 734 case 4: 735 case 5: 736 cursor_pos -= 4; 737 get_volume_string(note->volparam, note->voleffect, buf); 738 fg = note->voleffect == VOLFX_PANNING ? 1 : 2; 739 if (cursor_pos == 0) 740 draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); 741 else 742 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); 743 return; 744 case 9: 745 cursor_pos = 6; 746 // fall through 747 case 6: 748 case 7: 749 case 8: 750 draw_effect_1(x, y, note, cursor_pos, fg, bg); 751 return; 752 } 753 754 if (note->note) { 755 get_note_string_short(note->note, buf); 756 draw_char(buf[0], x, y, fg, bg); 757 } else if (note->instrument) { 758 num99tostr(note->instrument, buf); 759 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); 760 } else if (note->voleffect) { 761 if (cursor_pos != 0) 762 fg = (note->voleffect == VOLFX_PANNING) ? 1 : 2; 763 get_volume_string(note->volparam, note->voleffect, buf); 764 draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); 765 } else if (note->effect || note->param) { 766 draw_effect_1(x, y, note, cursor_pos, fg, bg); 767 } else { 768 draw_char(173, x, y, fg, bg); 769 } 770 } 771 772 void draw_mask_1(int x, int y, int mask, int cursor_pos, int fg, int bg) 773 { 774 char c = 143; 775 776 switch (cursor_pos) { 777 case 0: case 1: 778 c = MASK_CHAR(MASK_NOTE, 0, 1); 779 break; 780 case 2: case 3: 781 c = MASK_CHAR(MASK_INSTRUMENT, 2, 3); 782 break; 783 case 4: case 5: 784 c = MASK_CHAR(MASK_VOLUME, 4, 5); 785 break; 786 case 6: 787 c = MASK_CHAR(MASK_EFFECT, 6, 0); 788 break; 789 case 7: case 8: 790 c = MASK_CHAR(MASK_EFFECT, 7, 8); 791 break; 792 }; 793 794 draw_char(c, x, y, fg, bg); 795 } 796 797 /* --------------------------------------------------------------------- */ 798 /* 6-column track view (totally new!) */ 799 800 void draw_channel_header_6(int chan, int x, int y, int fg) 801 { 802 char buf[8]; 803 sprintf(buf, "Chnl%02d", chan); 804 draw_text(buf, x, y, fg, 1); 805 } 806 807 void draw_note_6(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) 808 { 809 char note_buf[4], ins_buf[3], vol_buf[3]; 810 int fg1, bg1, fg2, bg2; 811 812 #ifdef USE_LOWERCASE_NOTES 813 814 get_note_string_short(note->note, note_buf); 815 if (note->instrument) 816 num99tostr(note->instrument, ins_buf); 817 else 818 ins_buf[0] = ins_buf[1] = 173; 819 /* note & instrument */ 820 draw_text(note_buf, x, y, 6, bg); 821 fg1 = fg2 = (note->instrument ? 10 : 2); 822 bg1 = bg2 = bg; 823 switch (cursor_pos) { 824 case 0: 825 draw_char(note_buf[0], x, y, 0, 3); 826 break; 827 case 1: 828 draw_char(note_buf[1], x + 1, y, 0, 3); 829 break; 830 case 2: 831 fg1 = 0; 832 bg1 = 3; 833 break; 834 case 3: 835 fg2 = 0; 836 bg2 = 3; 837 break; 838 } 839 840 #else 841 842 get_note_string(note->note, note_buf); 843 844 if (cursor_pos == 0) 845 draw_char(note_buf[0], x, y, 0, 3); 846 else 847 draw_char(note_buf[0], x, y, fg, bg); 848 849 bg1 = bg2 = bg; 850 switch ((unsigned char) note_buf[0]) { 851 case '^': 852 case '~': 853 case 0xCD: // note off 854 case 0xAD: // dot (empty) 855 if (cursor_pos == 1) 856 draw_char(note_buf[1], x + 1, y, 0, 3); 857 else 858 draw_char(note_buf[1], x + 1, y, fg, bg); 859 break; 860 default: 861 draw_half_width_chars(note_buf[1], note_buf[2], x + 1, y, 862 fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); 863 break; 864 } 865 866 #endif 867 868 if (note->instrument) 869 num99tostr(note->instrument, ins_buf); 870 else 871 ins_buf[0] = ins_buf[1] = 173; 872 873 fg1 = fg2 = (note->instrument ? 10 : 2); 874 bg1 = bg2 = bg; 875 switch (cursor_pos) { 876 case 2: 877 fg1 = 0; 878 bg1 = 3; 879 break; 880 case 3: 881 fg2 = 0; 882 bg2 = 3; 883 break; 884 } 885 886 draw_half_width_chars(ins_buf[0], ins_buf[1], x + 2, y, fg1, bg1, fg2, bg2); 887 /* volume */ 888 get_volume_string(note->volparam, note->voleffect, vol_buf); 889 890 switch (note->voleffect) { 891 case VOLFX_NONE: 892 fg1 = 6; 893 break; 894 case VOLFX_PANNING: 895 fg1 = 10; 896 break; 897 case VOLFX_TONEPORTAMENTO: 898 case VOLFX_VIBRATOSPEED: 899 case VOLFX_VIBRATODEPTH: 900 fg1 = 6; 901 break; 902 default: 903 fg1 = 12; 904 break; 905 } 906 fg2 = fg1; 907 bg1 = bg2 = bg; 908 909 switch (cursor_pos) { 910 case 4: 911 fg1 = 0; 912 bg1 = 3; 913 break; 914 case 5: 915 fg2 = 0; 916 bg2 = 3; 917 break; 918 } 919 draw_half_width_chars(vol_buf[0], vol_buf[1], x + 3, y, fg1, bg1, fg2, bg2); 920 921 /* effect value */ 922 fg1 = fg2 = 10; 923 bg1 = bg2 = bg; 924 switch (cursor_pos) { 925 case 7: 926 fg1 = 0; 927 bg1 = 3; 928 break; 929 case 8: 930 fg2 = 0; 931 bg2 = 3; 932 break; 933 case 9: 934 fg1 = fg2 = 0; 935 bg1 = bg2 = 3; 936 cursor_pos = 6; // hack 937 break; 938 } 939 draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], 940 hexdigits[note->param & 0xf], 941 x + 5, y, fg1, bg1, fg2, bg2); 942 943 /* effect */ 944 draw_char(get_effect_char(note->effect), x + 4, y, 945 cursor_pos == 6 ? 0 : 2, cursor_pos == 6 ? 3 : bg); 946 } 947 948 void draw_mask_6(int x, int y, int mask, int cursor_pos, int fg, int bg) 949 { 950 char buf[] = { 951 MASK_CHAR(MASK_NOTE, 0, 0), 952 MASK_CHAR(MASK_NOTE, 0, 1), 953 MASK_CHAR(MASK_INSTRUMENT, 2, 3), 954 MASK_CHAR(MASK_VOLUME, 4, 5), 955 MASK_CHAR(MASK_EFFECT, 6, 0), 956 MASK_CHAR(MASK_EFFECT, 7, 8), 957 0, 958 }; 959 960 draw_text(buf, x, y, fg, bg); 961 } 962 963