A whole lot of things I didn't feel like making separate commits for... I know.

- Added VU bars for Win-6 and paino rolls for Win-7
- Wins now start at 1 instead of 0.
- Instruments now show up in the bottom line
- Resizing the terminal doesn't break everything
- Proper clearing
- Removed the auto-centering because it sucked
This commit is contained in:
Wirlaburla 2023-03-03 00:44:30 -06:00
parent e737780bb9
commit b3e0256bb6

View File

@ -17,11 +17,14 @@
static char *note_name[] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " }; static char *note_name[] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " };
void updateTrack(char* name, char* type); void updateTrack(char* name, char* type);
void renderTrack(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi);
void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi); void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi);
void renderChannels(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi);
void renderInstruments(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi);
char getEffectType(int i); char getEffectType(int i);
static char *device = "default"; static char *device = "default";
int chanOffset = 0; int detail = 1; int vol = 100; int chanOffset = 0; int insOffset = 0; int detail = 2; int vol = 100; int loop_times = 0;
bool looper = false, is_stopped = false; bool looper = false, is_stopped = false;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
printf("Trakker %s (with libxmp %s)\n", VERSION, xmp_version); printf("Trakker %s (with libxmp %s)\n", VERSION, xmp_version);
@ -92,10 +95,12 @@ int main(int argc, char *argv[]) {
xmp_start_player(c, SAMPLERATE, 0); xmp_start_player(c, SAMPLERATE, 0);
updateTrack(mi.mod->name, mi.mod->type); updateTrack(mi.mod->name, mi.mod->type);
while (true) { while (true) {
xmp_get_frame_info(c, &fi); xmp_get_frame_info(c, &fi);
if (xmp_play_frame(c) != 0 && !is_stopped) break; if (xmp_play_frame(c) != 0 && !is_stopped) break;
if (!looper && fi.loop_count > 0) break; if (fi.loop_count > loop_times)
if (looper) loop_times = fi.loop_count;
else break;
// Print Top-Right time // Print Top-Right time
mvprintw( mvprintw(
@ -120,26 +125,37 @@ int main(int argc, char *argv[]) {
if ((key = wgetch(win)) != 0) { if ((key = wgetch(win)) != 0) {
vol = xmp_get_player(c, XMP_PLAYER_VOLUME); vol = xmp_get_player(c, XMP_PLAYER_VOLUME);
switch (key) { switch (key) {
case KEY_RESIZE:
werase(stdscr);
updateTrack(mi.mod->name, mi.mod->type);
wresize(win, LINES-2, COLS-2);
break;
case ' ': // Pause/Play case ' ': // Pause/Play
time = fi.time; time = fi.time;
is_stopped = !is_stopped; is_stopped = !is_stopped;
break; break;
case KEY_LEFT: // Move Channels Left case KEY_LEFT: // Move Channels Left
if (chanOffset > 0) chanOffset--; if (chanOffset > 0 && detail < 7) chanOffset--;
break; break;
case KEY_RIGHT: // Move Channels Right case KEY_RIGHT: // Move Channels Right
if (chanOffset < mi.mod->chn-1) chanOffset++; if (chanOffset < mi.mod->chn-1 && detail < 7) chanOffset++;
break; break;
case KEY_UP: // Seek Up case KEY_UP: // Seek Up
if (is_stopped) fi.row--; if (insOffset > 0 && detail == 7) insOffset--;
else xmp_set_position(c, fi.pos-1); else if (detail < 7) fi.row--;
break; break;
case KEY_DOWN: // Seek Down case KEY_DOWN: // Seek Down
if (is_stopped) fi.row++; if (insOffset < mi.mod->ins-1 && detail == 7) insOffset++;
else xmp_set_position(c, fi.pos+1); else if (detail < 7) fi.row++;
break;
case KEY_PPAGE:
xmp_set_position(c, fi.pos-1);
break;
case KEY_NPAGE:
xmp_set_position(c, fi.pos+1);
break; break;
case '+': case '+':
if (vol < 100) xmp_set_player(c, XMP_PLAYER_VOLUME, vol+=5); if (vol < 200) xmp_set_player(c, XMP_PLAYER_VOLUME, vol+=5);
break; break;
case '-': case '-':
if (vol > 0) xmp_set_player(c, XMP_PLAYER_VOLUME, vol-=5); if (vol > 0) xmp_set_player(c, XMP_PLAYER_VOLUME, vol-=5);
@ -151,11 +167,13 @@ int main(int argc, char *argv[]) {
case '2': case '2':
case '3': case '3':
case '4': case '4':
case '5': case '5':
detail = std::atoi(key); case '6':
case '7':
detail = key-48;
break; break;
}; };
renderRows(win, &mi, &fi); renderTrack(win, &mi, &fi);
} }
if (!is_stopped) { if (!is_stopped) {
@ -168,8 +186,8 @@ int main(int argc, char *argv[]) {
pos = fi.pos; pos = fi.pos;
row = -1; row = -1;
} }
if (fi.row != row) { if (fi.row != row || detail >= 6) {
renderRows(win, &mi, &fi); renderTrack(win, &mi, &fi);
row = fi.row; row = fi.row;
fupdate = false; fupdate = false;
} }
@ -201,13 +219,13 @@ void updateTrack(char* name, char* type) {
); );
} }
void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) { void renderTrack(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
werase(win); werase(win);
move(LINES-1, 0); move(LINES-1, 0);
wclrtoeol(stdscr); wclrtoeol(stdscr);
mvprintw( mvprintw(
LINES-1, 0, LINES-1, 0,
"[%c] PAT:%02x:%02x/%02x BPM:%02u SPD:%02u CHAN:%02u/%02u VOL:%03u d%i %s", "[%c] PAT:%02x:%02x/%02x BPM:%02u SPD:%02u CHN:%02u/%02u INS:%02u/%02u VOL:%03u WIN:%i %s",
is_stopped?'x':'>', is_stopped?'x':'>',
fi->pos, fi->pos,
fi->pattern, fi->pattern,
@ -216,19 +234,31 @@ void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
fi->speed, fi->speed,
chanOffset+1, chanOffset+1,
mi->mod->chn, mi->mod->chn,
insOffset,
mi->mod->ins,
vol, vol,
detail+1, detail,
looper?"LOOP ":"" looper?"LOOP ":""
); );
int view_chanOffset = chanOffset; if (detail < 6) // Row views
int view_detail = detail; renderRows(win, mi, fi);
else if (detail == 6) //Channel views
renderChannels(win, mi, fi);
else if (detail == 7)
renderInstruments(win, mi, fi);
refresh();
wrefresh(win);
}
void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
int dlvl; int dlvl;
// Set proper sizes for channels. // Set proper sizes for channels.
if (detail == 5) dlvl = 19; if (detail == 5) dlvl = 19;
else if (detail == 4) dlvl = 15; else if (detail == 4) dlvl = 15;
else if (detail == 3) dlvl = 11; else if (detail == 3) dlvl = 11;
else if (detail == 2) dlvl = 7; else if (detail == 2) dlvl = 7;
else dlvl = 3; else dlvl = 2;
for (int y = 0; y < LINES - 2; y++) { for (int y = 0; y < LINES - 2; y++) {
int trow = (fi->row - ((LINES - 2) / 2))+y; int trow = (fi->row - ((LINES - 2) / 2))+y;
if (trow > fi->num_rows-1 || trow < 0) { continue;} if (trow > fi->num_rows-1 || trow < 0) { continue;}
@ -241,14 +271,13 @@ void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
} }
wmove(win, y, 0); wmove(win, y, 0);
wprintw(win, "%02X", trow); wprintw(win, "%02X", trow);
int coff = ((COLS - 2) % dlvl);
int maxcol = -1; int maxcol = -1;
for (int i = chanOffset; i < mi->mod->chn; i++) { for (int i = chanOffset; i < mi->mod->chn; i++) {
if (coff+(((i-chanOffset)+1)*dlvl)+dlvl > COLS) { if (1+(((i-chanOffset)+1)*dlvl)+dlvl > COLS) {
maxcol = i; maxcol = i;
break; break;
} }
wmove(win, y, coff+((i-chanOffset)*dlvl)+2); wmove(win, y, 1+((i-chanOffset)*dlvl)+2);
int track = mi->mod->xxp[fi->pattern]->index[i]; int track = mi->mod->xxp[fi->pattern]->index[i];
struct xmp_event event = mi->mod->xxt[track]->event[trow]; struct xmp_event event = mi->mod->xxt[track]->event[trow];
if (i > 0 && i == chanOffset) wprintw(win, "<"); if (i > 0 && i == chanOffset) wprintw(win, "<");
@ -319,19 +348,50 @@ void renderRows(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
wprintw(win, " "); wprintw(win, " ");
} }
} }
view_chanOffset = chanOffset;
view_detail = detail;
} }
if (maxcol < mi->mod->chn && maxcol > 0) wprintw(win, ">"); if (maxcol < mi->mod->chn && maxcol > 0) wprintw(win, ">");
else wprintw(win, "|"); else wprintw(win, "|");
} }
refresh(); }
wrefresh(win);
void renderChannels(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
int chns = mi->mod->chn;
for (int y = chanOffset; y < chns; y++) {
struct xmp_channel_info cinfo = fi->channel_info[y];
if (y > (LINES - 3)+chanOffset) break;
wmove(win, y-chanOffset, 0);
int cvol = (cinfo.volume * (COLS - 7)) / (64 * (vol / 100));
wprintw(win, "%02X [", y);
for (int c = 0; c < COLS - 7; c++) {
if (c < cvol) wprintw(win, "#");
else wprintw(win, " ");
}
wprintw(win, "]");
}
}
void renderInstruments(WINDOW* win, xmp_module_info *mi, xmp_frame_info *fi) {
int ins = mi->mod->ins;
for (int y = insOffset; y < ins; y++) {
if (y > (LINES - 3)+insOffset) break;
wmove(win, y-insOffset, 0);
wprintw(win, "%02X [", y);
for (int c = 0; c < mi->mod->chn; c++) {
struct xmp_channel_info cinfo = fi->channel_info[c];
int note = (cinfo.note * (COLS - 7)) / 144;
if (cinfo.instrument != y) continue;
wmove(win, y-insOffset, note);
if (cinfo.volume >= 16) wprintw(win, "#");
else if (cinfo.volume > 0) wprintw(win, "-");
}
wmove(win, y-insOffset, COLS-3);
wprintw(win, "]");
}
} }
char getEffectType(int i) { char getEffectType(int i) {
// The effect type characters are so strange to me. // The effect type characters are so strange to me.
// They make absolutely no sense in why it's setup this way. // They make absolutely no sense in why it's set up this way.
// Maybe I'm mega stupid right now but this is all of the IT // Maybe I'm mega stupid right now but this is all of the IT
// formats effects, so maybe this will cover everything enough. // formats effects, so maybe this will cover everything enough.
// Broken, but not crashy-broken anymore. // Broken, but not crashy-broken anymore.