diff --git a/src/main.cpp b/src/main.cpp index 984510d..f96fe8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -14,8 +15,8 @@ #define SAMPLERATE 48000 #define BUFFER_SIZE 250000 -static char *note_name[] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " }; -static char* pages[] = { "[1] Info", "[2] Pattern", "[3] Channel Bars", "[4] Piano Roll", "[5] About" }; +static std::string note_name[] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " }; +static std::string pages[] = { "1. Info", "2. Pattern", "3. Bars", "4. Piano Roll", "5. Config", "6. Help" }; static char* device = "default"; char* file; @@ -30,11 +31,103 @@ int hOffset = 0; int vMin = 0; int vMax = 2048; int vOffset = 0; int looped = 0; +int prMin = 255; +int prMax = 0; bool stopped; bool loop; +bool ptnChans = true; +bool dynamicRoll = true; +bool ptnOrder = true; std::map efxtable; std::map efxmemtable; +bool colorMonochrome() { + // Primary Background + init_pair(1, COLOR_BLACK, COLOR_BLACK); + // Inactive Section + init_pair(2, COLOR_WHITE, COLOR_BLACK); + // Active Section + init_pair(3, COLOR_BLACK, COLOR_WHITE); + // Display + init_pair(4, COLOR_WHITE, COLOR_BLACK); + // Display Row# + init_pair(5, COLOR_WHITE, COLOR_BLACK); + // Display Playhead + init_pair(6, COLOR_BLACK, COLOR_WHITE); + // Display Playhead Row# + init_pair(7, COLOR_BLACK, COLOR_WHITE); + // Display Stopped Playhead + init_pair(8, COLOR_WHITE, COLOR_BLACK); + // Display Stopped Playhead Row# + init_pair(9, COLOR_WHITE, COLOR_BLACK); + // Display VU Bar Low + init_pair(10, COLOR_WHITE, COLOR_WHITE); + // Display VU Bar Medium + init_pair(11, COLOR_WHITE, COLOR_WHITE); + // Display VU Bar High + init_pair(12, COLOR_WHITE, COLOR_WHITE); + // Inverted Text + init_pair(13, COLOR_WHITE, COLOR_BLACK); +} + +bool colorLimited() { + // Primary Background + init_pair(1, COLOR_BLACK, 8); + // Inactive Section + init_pair(2, COLOR_BLACK, COLOR_WHITE); + // Active Section + init_pair(3, COLOR_BLACK, COLOR_CYAN); + // Display + init_pair(4, COLOR_WHITE, COLOR_BLACK); + // Display Row# + init_pair(5, COLOR_YELLOW, COLOR_BLACK); + // Display Playhead + init_pair(6, COLOR_WHITE, COLOR_BLUE); + // Display Playhead Row# + init_pair(7, COLOR_YELLOW, COLOR_BLUE); + // Display Stopped Playhead + init_pair(8, COLOR_WHITE, COLOR_RED); + // Display Stopped Playhead Row# + init_pair(9, COLOR_YELLOW, COLOR_RED); + // Display VU Bar Low + init_pair(10, COLOR_WHITE, COLOR_GREEN); + // Display VU Bar Medium + init_pair(11, COLOR_WHITE, COLOR_YELLOW); + // Display VU Bar High + init_pair(12, COLOR_WHITE, COLOR_RED); + // Inverted Text + init_pair(13, COLOR_WHITE, COLOR_BLACK); +} + +void colorFull() { + // Primary Background + init_pair(1, COLOR_BLACK, 8); + // Inactive Section + init_pair(2, 8, 7); + // Active Section + init_pair(3, 0, 12); + // Display + init_pair(4, 7, COLOR_BLACK); + // Display Row# + init_pair(5, 3, COLOR_BLACK); + // Display Playhead + init_pair(6, COLOR_WHITE, COLOR_BLUE); + // Display Playhead Row# + init_pair(7, COLOR_YELLOW, COLOR_BLUE); + // Display Stopped Playhead + init_pair(8, COLOR_WHITE, COLOR_RED); + // Display Stopped Playhead Row# + init_pair(9, COLOR_YELLOW, COLOR_RED); + // Display VU Bar Low + init_pair(10, COLOR_WHITE, COLOR_GREEN); + // Display VU Bar Medium + init_pair(11, COLOR_WHITE, COLOR_YELLOW); + // Display VU Bar High + init_pair(12, COLOR_WHITE, COLOR_RED); + // Inverted Text + init_pair(13, COLOR_WHITE, COLOR_BLACK); +} + int main(int argc, char *argv[]) { printf("TRAKKER %s (using XMP %s)\n", TRAKKER_VERSION, xmp_version); for (int a = 1; a < argc; ++a) { @@ -49,25 +142,13 @@ int main(int argc, char *argv[]) { printf(" 2 8bit\n"); printf(" 3 Full\n"); printf("-s Stereo Seperation\n"); - printf("-t Set module emulation type.\n"); - printf(" auto Autodetect mode (default)\n"); - printf(" mod Play as a generic MOD player\n"); - printf(" noisetracker Play using Noisetracker quirks\n"); - printf(" protracker Play using Protracker 1/2 quirks\n"); - printf(" s3m Play as a generic S3M player\n"); - printf(" st3 Play using ST3 bug emulation\n"); - printf(" st3gus Play using ST3+GUS quirks\n"); - printf(" xm Play as a generic XM player\n"); - printf(" ft2 Play using FT2 bug emulation\n"); - printf(" it Play using IT quirks\n"); - printf(" itsmp Play using IT sample mode quirks\n"); exit(0); } else if (strcmp(argv[a], "-d") == 0) { int newdisplay = atoi(argv[a+1])-1; - if (newdisplay > 4 || newdisplay < 0) + if (newdisplay > 5 || newdisplay < 0) fprintf(stderr, "Display argument is invalid.\n"); else { - printf("Setting display to \"%s\"\n", pages[newdisplay]); + printf("Setting display to \"%s\"\n", pages[newdisplay].c_str()); display = newdisplay; } a++; @@ -138,72 +219,14 @@ int main(int argc, char *argv[]) { initscr(); start_color(); - if (colorMode == 1) goto colorless; - else if (colorMode == 2) goto color_8; - else if (colorMode == 3) goto color_full; - - if (has_colors() == TRUE) { - if (can_change_color() == TRUE) { - color_full: - // Primary Background - init_pair(1, COLOR_BLACK, 8); - // Inactive Section - init_pair(2, 8, 7); - // Active Section - init_pair(3, 0, 12); - // Display - init_pair(4, 7, COLOR_BLACK); - // Display Row# - init_pair(5, 3, COLOR_BLACK); - // Display Playhead - init_pair(6, COLOR_WHITE, COLOR_BLUE); - // Display Playhead Row# - init_pair(7, COLOR_YELLOW, COLOR_BLUE); - // Display Stopped Playhead - init_pair(8, COLOR_WHITE, COLOR_RED); - // Display Stopped Playhead Row# - init_pair(9, COLOR_YELLOW, COLOR_RED); + if ((has_colors() == TRUE && colorMode == 0) || colorMode >= 2) { + if ((can_change_color() == TRUE && colorMode == 0) || colorMode == 3) { + colorFull(); } else { - color_8: - // Primary Background - init_pair(1, COLOR_BLACK, 8); - // Inactive Section - init_pair(2, COLOR_BLACK, COLOR_WHITE); - // Active Section - init_pair(3, COLOR_BLACK, COLOR_CYAN); - // Display - init_pair(4, COLOR_WHITE, COLOR_BLACK); - // Display Row# - init_pair(5, COLOR_YELLOW, COLOR_BLACK); - // Display Playhead - init_pair(6, COLOR_WHITE, COLOR_BLUE); - // Display Playhead Row# - init_pair(7, COLOR_YELLOW, COLOR_BLUE); - // Display Stopped Playhead - init_pair(8, COLOR_WHITE, COLOR_RED); - // Display Stopped Playhead Row# - init_pair(9, COLOR_YELLOW, COLOR_RED); + colorLimited(); } } else { - colorless: - // Primary Background - init_pair(1, COLOR_BLACK, COLOR_BLACK); - // Inactive Section - init_pair(2, COLOR_WHITE, COLOR_BLACK); - // Active Section - init_pair(3, COLOR_BLACK, COLOR_WHITE); - // Display - init_pair(4, COLOR_WHITE, COLOR_BLACK); - // Display Row# - init_pair(5, COLOR_WHITE, COLOR_BLACK); - // Display Playhead - init_pair(6, COLOR_BLACK, COLOR_WHITE); - // Display Playhead Row# - init_pair(7, COLOR_BLACK, COLOR_WHITE); - // Display Stopped Playhead - init_pair(8, COLOR_WHITE, COLOR_BLACK); - // Display Stopped Playhead Row# - init_pair(9, COLOR_WHITE, COLOR_BLACK); + colorMonochrome(); } cbreak(); @@ -245,17 +268,29 @@ int main(int argc, char *argv[]) { break; case 'q': goto end; break; - case KEY_LEFT: // Move Channels Left - if (hOffset > hMin) hOffset--; + case KEY_LEFT: case 'a': // Move Channels Left + if (hOffset > hMin) hOffset-=1; break; - case KEY_RIGHT: // Move Channels Right - if (hOffset < hMax) hOffset++; + case KEY_RIGHT: case 'd': // Move Channels Right + if (hOffset < hMax) hOffset+=1; break; - case KEY_UP: // Seek Up - if (vOffset > vMin) vOffset--; + case KEY_UP: case 'w': // Seek Up + if (vOffset > vMin) vOffset-=1; break; - case KEY_DOWN: // Seek Down - if (vOffset < vMax) vOffset++; + case KEY_DOWN: case 's': // Seek Down + if (vOffset < vMax) vOffset+=1; + break; + case 'A': // Move Channels Left (faster) + if (hOffset > hMin) hOffset-=5; + break; + case 'D': // Move Channels Right (faster) + if (hOffset < hMax) hOffset+=5; + break; + case 'W': // Seek Up (faster) + if (vOffset > vMin) vOffset-=5; + break; + case 'S': // Seek Down (faster) + if (vOffset < vMax) vOffset+=5; break; case KEY_PPAGE: if (vOffset > vMin + LINES-6) vOffset-=(LINES-5); @@ -265,18 +300,14 @@ int main(int argc, char *argv[]) { if (vOffset < vMax - LINES-6) vOffset+=(LINES-5); else vOffset = vMax; break; - case 10: - hOffset = 0; - vOffset = 0; - break; - case ' ': // Pause/Play + case 10: case ' ': // Pause/Play xfi.time-=20; - stopped = !stopped; + stopped = !stopped; break; - case '.': + case '+': case '=': if (vol < 200) xmp_set_player(xc, XMP_PLAYER_VOLUME, vol+=5); break; - case ',': + case '-': if (vol > 0) xmp_set_player(xc, XMP_PLAYER_VOLUME, vol-=5); break; case '[': @@ -295,11 +326,31 @@ int main(int argc, char *argv[]) { case '3': case '4': case '5': + case '6': display = key-49; displayChanged = true; break; + case 27: // ALT + if ((key = getch()) != 0) { + switch (key) { + case '1': + ptnChans = !ptnChans; + break; + case '2': + prMin = 255; prMax = 0; + dynamicRoll = !dynamicRoll; + break; + case '3': + ptnOrder = !ptnOrder; + break; + } + } + break; + case 'R': + hOffset = vOffset = 0; + break; }; - renderTrack(&xmi, &xfi); + displayHeader(&xmi, &xfi); } if (displayChanged) { @@ -314,7 +365,7 @@ int main(int argc, char *argv[]) { if (display == d) tpair = COLOR_PAIR(3); else tpair = COLOR_PAIR(2); attron(tpair); - printw(" "); printw(pages[d]); printw(" "); + printw(" "); printw(pages[d].c_str()); printw(" "); attroff(tpair); printw(" "); } @@ -324,21 +375,21 @@ int main(int argc, char *argv[]) { } if (!stopped) { - frames = snd_pcm_bytes_to_frames(handle, xfi.buffer_size); - if (snd_pcm_writei(handle, xfi.buffer, frames) < 0) { - snd_pcm_prepare(handle); - } - if (xfi.pos != pos) { pos = xfi.pos; row = -1; } if (xfi.row != row) { row = xfi.row; - renderTrack(&xmi, &xfi); + displayHeader(&xmi, &xfi); } wrefresh(tab); wrefresh(dis); + + frames = snd_pcm_bytes_to_frames(handle, xfi.buffer_size); + if (snd_pcm_writei(handle, xfi.buffer, frames) < 0) { + snd_pcm_prepare(handle); + } } else goto keys; } end: @@ -375,7 +426,7 @@ void createWindows() { wrefresh(dis); } -void renderTrack(xmp_module_info *mi, xmp_frame_info *fi) { +void displayHeader(xmp_module_info *mi, xmp_frame_info *fi) { werase(dis); wclrtoeol(tab); mvwaddstr(tab, 0, 1, mi->mod->name); @@ -388,96 +439,122 @@ void renderTrack(xmp_module_info *mi, xmp_frame_info *fi) { ((fi->total_time / 1000) / 60) % 60, (fi->total_time / 1000) % 60 ); + wmove(tab, 1, 0); + wclrtoeol(tab); mvwprintw(tab, 1, COLS-10, "VOL: %i%%", vol); mvwprintw(tab, 1, 1, "%i/%ibpm", fi->speed, fi->bpm); - mvwprintw(tab, LINES-2, 1, "%s %s", stopped?"STOPPED":"PLAYING", loop?"[L]":"[ ]"); + mvwprintw(tab, LINES-2, 1, "%s", stopped?"STOPPED":"PLAYING"); if (display == 0) { - renderInfo(mi, fi); + displayInfo(mi, fi); } else if (display == 1) { - renderRows(mi, fi); + displayPatterns(mi, fi); } else if (display == 2) { - renderChannels(mi, fi); + displayVolumes(mi, fi); } else if (display == 3) { - renderInstruments(mi, fi); + displayNoteRoll(mi, fi); + } else if (display == 4) { + displayPlayer(); } else { - renderAbout(); + displayHelp(); } refresh(); wrefresh(dis); wrefresh(tab); } -void renderInfo(xmp_module_info *mi, xmp_frame_info *fi) { +void displayInfo(xmp_module_info *mi, xmp_frame_info *fi) { wattron(dis, A_BOLD); - mvwaddstr(dis, 1-vOffset, 1, "Mode:"); - mvwaddstr(dis, 2-vOffset, 1, "Format:"); - mvwaddstr(dis, 3-vOffset, 1, "Stereo Mix:"); - mvwaddstr(dis, 4-vOffset, 1, "Channels:"); - mvwaddstr(dis, 6-vOffset, 1, "Instruments:"); - mvwaddstr(dis, (8+mi->mod->ins)-vOffset, 1, "Samples:"); + mvwaddstr(dis, 1-vOffset, 1, "Format:"); + mvwaddstr(dis, 2-vOffset, 1, "Stereo Mix:"); + mvwaddstr(dis, 3-vOffset, 1, "Channels:"); + mvwaddstr(dis, 5-vOffset, 1, "Instruments:"); + mvwaddstr(dis, (7+mi->mod->ins)-vOffset, 1, "Samples:"); wattroff(dis, A_BOLD); - mvwprintw(dis, 1-vOffset, 16, "%i", xmp_get_player(xc, XMP_PLAYER_MODE)); - mvwprintw(dis, 2-vOffset, 16, mi->mod->type); - mvwprintw(dis, 3-vOffset, 16, "%i%%", smix); - mvwprintw(dis, 4-vOffset, 16, "%i", mi->mod->chn); - mvwprintw(dis, 6-vOffset, 16, "%i", mi->mod->ins); - mvwprintw(dis, (8+mi->mod->ins)-vOffset, 16, "%i", mi->mod->smp); + mvwprintw(dis, 1-vOffset, 16, mi->mod->type); + mvwprintw(dis, 2-vOffset, 16, "%i%%", smix); + mvwprintw(dis, 3-vOffset, 16, "%i", mi->mod->chn); + mvwprintw(dis, 5-vOffset, 16, "%i", mi->mod->ins); + mvwprintw(dis, (7+mi->mod->ins)-vOffset, 16, "%i", mi->mod->smp); for (int xi = 0; xi < mi->mod->ins; xi++) { - mvwprintw(dis, xi+7-vOffset, 1, "[%02X] %s", xi, mi->mod->xxi[xi].name); + mvwprintw(dis, xi+6-vOffset, 1, "[%02X] %s", xi, mi->mod->xxi[xi].name); } for (int xs = 0; xs < mi->mod->smp; xs++) { - mvwprintw(dis, xs+(9+mi->mod->ins)-vOffset, 1, "[%02X] %s", xs, mi->mod->xxs[xs].name); + mvwprintw(dis, xs+(8+mi->mod->ins)-vOffset, 1, "[%02X] %s", xs, mi->mod->xxs[xs].name); } } -void renderAbout() { - wattron(dis, A_BOLD); - mvwaddstr(dis, 1-vOffset, 2, "######## ||##\\\\ //\\\\ || // || // ||### ||##\\\\"); - mvwaddstr(dis, 2-vOffset, 2, " || || || // \\\\ ||// ||// || || ||"); - mvwaddstr(dis, 3-vOffset, 2, " || ||##// ||##|| |#| |#| ||# ||##//"); - mvwaddstr(dis, 4-vOffset, 2, " || ||\\\\ || || ||\\\\ ||\\\\ || ||\\\\ "); - mvwaddstr(dis, 5-vOffset, 2, " || || \\\\ || || || \\\\ || \\\\ ||### || \\\\ "); - mvwaddstr(dis, 6-vOffset, 2, "================================================="); - mvwaddstr(dis, 8-vOffset, 1, "TRAKKER"); - mvwaddstr(dis, 9-vOffset, 1, "libXMP"); - - mvwaddstr(dis, 11-vOffset, 1, "[Spacebar]"); - mvwaddstr(dis, 12-vOffset, 1, "Number Keys"); - mvwaddstr(dis, 13-vOffset, 1, "[LF] and [RT]"); - mvwaddstr(dis, 14-vOffset, 1, "[UP] and [DN]"); - mvwaddstr(dis, 15-vOffset, 1, "[,] and [.]"); - mvwaddstr(dis, 16-vOffset, 1, "[Return]"); - mvwaddstr(dis, 17-vOffset, 1, "[L]"); - mvwaddstr(dis, 18-vOffset, 1, "[PGUP] and [PGDN]"); - mvwaddstr(dis, 19-vOffset, 1, "[[] and []]"); - wattroff(dis, A_BOLD); - - mvwaddstr(dis, 8-vOffset, 20, TRAKKER_VERSION); - mvwaddstr(dis, 9-vOffset, 20, xmp_version); - mvwaddstr(dis, 11-vOffset, 20, "Play/Pause"); - mvwaddstr(dis, 12-vOffset, 20, "Change Tab"); - mvwaddstr(dis, 13-vOffset, 20, "Change horizontal offset."); - mvwaddstr(dis, 14-vOffset, 20, "Change vertical offset."); - mvwaddstr(dis, 15-vOffset, 20, "Control volume"); - mvwaddstr(dis, 16-vOffset, 20, "Reset Display"); - mvwaddstr(dis, 17-vOffset, 20, "Toggle Loop"); - mvwaddstr(dis, 18-vOffset, 20, "Scroll vertically per page."); - mvwaddstr(dis, 19-vOffset, 20, "Change stereo mixing."); -} - -void renderRows(xmp_module_info *mi, xmp_frame_info *fi) { +void displayPatterns(xmp_module_info *mi, xmp_frame_info *fi) { int chnsize = 15; - for (int j = 0; j < mi->mod->len; j++) { - if (mi->mod->xxo[j] == 0xFF) continue; - chtype patpair = (j == fi->pos)?COLOR_PAIR(6):COLOR_PAIR(4); - wattron(dis, patpair); - mvwprintw(dis, LINES-5, (COLS/2)+(j*3)-(fi->pos*3)-3, "%02X", mi->mod->xxo[j]); - wattroff(dis, patpair); + if (ptnOrder) { + for (int j = 0; j < mi->mod->len; j++) { + if (mi->mod->xxo[j] == 0xFF) continue; + chtype patpair = (j == fi->pos)?COLOR_PAIR(6):COLOR_PAIR(4); + wattron(dis, patpair); + mvwprintw(dis, LINES-5, (COLS/2)+(j*3)-(fi->pos*3)-3, "%02X", mi->mod->xxo[j]); + wattroff(dis, patpair); + } } wattroff(tab, COLOR_PAIR(5)); - for (int y = 0; y < LINES - 5; y++) { + for (int y = 0; y < LINES - (5-(!ptnOrder)); y++) { + if (ptnChans && y == 0) { + chtype chnvw = COLOR_PAIR(5); + chtype vollo = COLOR_PAIR(10); + chtype volmd = COLOR_PAIR(11); + chtype volhi = COLOR_PAIR(12); + int cxpos = 3; + wmove(dis, 0, cxpos); + for (int i = 0; i < mi->mod->chn; i++) { + struct xmp_channel_info cinfo = fi->channel_info[i]; + int voll = cinfo.volume * (255-cinfo.pan)/255; + if (voll >= 64) wattron(dis, volhi); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, volhi); + if (voll >= 48) wattron(dis, volmd); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, volmd); + if (voll >= 32) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + if (voll >= 16) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + if (voll > 0) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + + wattron(dis, chnvw); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + char *cbuf = new char[2]; + sprintf(cbuf, "%02X", i); + mvwaddch(dis, 0, (cxpos++)-hOffset, cbuf[0]); + mvwaddch(dis, 0, (cxpos++)-hOffset, cbuf[1]); + free(cbuf); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, chnvw); + + int volr = cinfo.volume * cinfo.pan/255; + if (volr > 0) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + if (volr >= 16) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + if (volr >= 32) wattron(dis, vollo); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, vollo); + if (volr >= 48) wattron(dis, volmd); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, volmd); + if (volr >= 64) wattron(dis, volhi); + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + wattroff(dis, volhi); + + mvwaddch(dis, 0, (cxpos++)-hOffset, ' '); + } + continue; + } int trow = (fi->row - ((LINES - 2) / 2))+y; if (trow > fi->num_rows-1 || trow < 0) { continue; } chtype numpair = COLOR_PAIR((trow==fi->row)?(stopped?9:7):5); @@ -504,7 +581,7 @@ void renderRows(xmp_module_info *mi, xmp_frame_info *fi) { if (event.note > 0x80) snprintf(note, 4, "==="); else if (event.note > 0) - snprintf(note, 4, "%s%d", note_name[event.note % 12], event.note / 12); + snprintf(note, 4, "%s%d", note_name[event.note % 12].c_str(), event.note / 12); else snprintf(note, 4, "..."); @@ -513,7 +590,7 @@ void renderRows(xmp_module_info *mi, xmp_frame_info *fi) { if (event.vol != 0) snprintf(vol, 4, "v%02X", event.vol-1); - else if (event.note != 0) + else if (event.note > 0 && event.note <= 0x80) snprintf(vol, 4, "v40"); else snprintf(vol, 4, "..."); @@ -536,7 +613,7 @@ void renderRows(xmp_module_info *mi, xmp_frame_info *fi) { } } -void renderChannels(xmp_module_info *mi, xmp_frame_info *fi) { +void displayVolumes(xmp_module_info *mi, xmp_frame_info *fi) { int chns = mi->mod->chn; chtype no_pair = COLOR_PAIR(5); for (int y = vOffset; y < chns; y++) { @@ -555,28 +632,97 @@ void renderChannels(xmp_module_info *mi, xmp_frame_info *fi) { } } -void renderInstruments(xmp_module_info *mi, xmp_frame_info *fi) { +void displayNoteRoll(xmp_module_info *mi, xmp_frame_info *fi) { int ins = mi->mod->ins; chtype no_pair = COLOR_PAIR(5); for (int y = vOffset; y < ins; y++) { + if (!dynamicRoll) { prMin = 0; prMax = 144; } if (y > (LINES - 5)+vOffset || y < 0) continue; wmove(dis, y-vOffset, 0); wattron(dis, no_pair); wprintw(dis, "%02X", y); wattroff(dis, no_pair); + wclrtoeol(dis); for (int c = 0; c < mi->mod->chn; c++) { struct xmp_channel_info cinfo = fi->channel_info[c]; - int note = (cinfo.note * (COLS - 4)) / 144; + + if (dynamicRoll) { + if (cinfo.note < prMin) + prMin = cinfo.note-1; + else if (cinfo.note > prMax && cinfo.note != 255) + prMax = cinfo.note+1; + } + + int note = ((cinfo.note - prMin) * (COLS - 5)) / (dynamicRoll?(prMax - prMin):96); if (cinfo.instrument != y) continue; + wmove(dis, y-vOffset, note+3); - if (cinfo.volume >= 32) waddstr(dis, "#"); - else if (cinfo.volume >= 16) waddstr(dis, "="); - else if (cinfo.volume > 0) waddstr(dis, "-"); + if (cinfo.volume >= 32) + waddstr(dis, "#"); + else if (cinfo.volume >= 16 && (char)mvwinch(dis, y-vOffset, note+3) != '#') + waddstr(dis, "="); + else if (cinfo.volume > 0 && ((char)mvwinch(dis, y-vOffset, note+3) != '-' || (char)mvwinch(dis, y-vOffset, note+3) != '#')) + waddstr(dis, "-"); } wmove(dis, y, COLS-4); } } +void displayPlayer() { + wattron(dis, A_BOLD); + mvwaddstr(dis, 1-vOffset, 1, "Loop"); + mvwaddstr(dis, 2-vOffset, 1, "Stereo Seperation"); + mvwaddstr(dis, 3-vOffset, 1, "Color Mode"); + + mvwaddstr(dis, 5-vOffset, 1, "1. Pattern Channels"); + mvwaddstr(dis, 6-vOffset, 1, "2. Dynamic Note Roll"); + mvwaddstr(dis, 7-vOffset, 1, "3. Pattern Order"); + wattroff(dis, A_BOLD); + + mvwaddstr(dis, 1-vOffset, 20, loop?"[ #] YES":"[# ] NO"); + mvwprintw(dis, 2-vOffset, 20, "%i%%", smix); + mvwprintw(dis, 3-vOffset, 20, "%i", colorMode); + + mvwaddstr(dis, 5-vOffset, 22, ptnChans?"[ #] YES":"[# ] NO"); + mvwaddstr(dis, 6-vOffset, 22, dynamicRoll?"[ #] YES":"[# ] NO"); + mvwaddstr(dis, 7-vOffset, 22, ptnOrder?"[ #] YES":"[# ] NO"); +} + +void displayHelp() { + wattron(dis, A_BOLD); + mvwaddstr(dis, 1-vOffset, 2, " / ######## TRAKKER"); + mvwaddstr(dis, 2-vOffset, 2, " / // / libxmp"); + mvwaddstr(dis, 3-vOffset, 2, "/ // / "); + mvwaddstr(dis, 4-vOffset, 2, " // / by Nick G. (Wirlaburla)"); + mvwaddstr(dis, 5-vOffset, 2, " // / Licensed under the GPLv3"); + + mvwaddstr(dis, 7-vOffset, 1, "Play/Pause........"); + mvwaddstr(dis, 8-vOffset, 1, "Switch Tabs......."); + mvwaddstr(dis, 9-vOffset, 1, "Fast Shift........"); + mvwaddstr(dis, 10-vOffset, 1, "Horizontal Shift.."); + mvwaddstr(dis, 11-vOffset, 1, "Vertical Shift...."); + mvwaddstr(dis, 12-vOffset, 1, "Volume............"); + mvwaddstr(dis, 13-vOffset, 1, "Refresh..........."); + mvwaddstr(dis, 14-vOffset, 1, "Vertical Scroll..."); + mvwaddstr(dis, 15-vOffset, 1, "Stero Seperation.."); + mvwaddstr(dis, 16-vOffset, 1, "Option Toggle....."); + wattroff(dis, A_BOLD); + + mvwaddstr(dis, 1-vOffset, 25, TRAKKER_VERSION); + mvwaddstr(dis, 2-vOffset, 25, xmp_version); + + mvwaddstr(dis, 7-vOffset, 20, "Space"); + mvwaddstr(dis, 8-vOffset, 20, "Tab"); + mvwaddstr(dis, 9-vOffset, 20, "Shift + W A S D"); + mvwaddstr(dis, 10-vOffset, 20, "Left Arrow / Right Arrow OR A / D"); + mvwaddstr(dis, 11-vOffset, 20, "Up Arrow / Down Arrow OR W / S"); + mvwaddstr(dis, 12-vOffset, 20, "+ / -"); + mvwaddstr(dis, 13-vOffset, 20, "R"); + mvwaddstr(dis, 14-vOffset, 20, "Page-Up / Page-Down"); + mvwaddstr(dis, 15-vOffset, 20, "[ / ]"); + mvwaddstr(dis, 16-vOffset, 20, "Alt + 0-9"); +} + void generateEffectsTable(char* type) { if (isPartOf(type, "669")) { addToEffects(96, 'A', true); diff --git a/src/trakker.h b/src/trakker.h index b0f0d79..a216924 100644 --- a/src/trakker.h +++ b/src/trakker.h @@ -9,12 +9,13 @@ WINDOW *tab; void destroyWindows(); void createWindows(); -void renderInfo(xmp_module_info *mi, xmp_frame_info *fi); -void renderAbout(); -void renderTrack(xmp_module_info *mi, xmp_frame_info *fi); -void renderRows(xmp_module_info *mi, xmp_frame_info *fi); -void renderChannels(xmp_module_info *mi, xmp_frame_info *fi); -void renderInstruments(xmp_module_info *mi, xmp_frame_info *fi); +void displayHeader(xmp_module_info *mi, xmp_frame_info *fi); +void displayInfo(xmp_module_info *mi, xmp_frame_info *fi); +void displayPatterns(xmp_module_info *mi, xmp_frame_info *fi); +void displayVolumes(xmp_module_info *mi, xmp_frame_info *fi); +void displayNoteRoll(xmp_module_info *mi, xmp_frame_info *fi); +void displayPlayer(); +void displayHelp(); void generateEffectsTable(char* type); void addToEffects(int id, char efx, bool mem); bool isPartOf(char* w1, char* w2);