home *** CD-ROM | disk | FTP | other *** search
- /*
- * screen.c - Handling of the screen using the ncurses-package.
- *
- * (C) 1994 Mikael Nordqvist (d91mn@efd.lth.se, mech@df.lth.se)
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <ncurses.h>
-
- #include "mod.h"
-
- #define ATTR_LINE (COLOR_PAIR(7) | A_ALTCHARSET)
- #define ATTR_BOLDLINE (COLOR_PAIR(7) | A_ALTCHARSET | A_BOLD)
-
- #define ATTR_FILE ATTR_LINE
- #define ATTR_BOLDFILE ATTR_BOLDLINE
- #define ATTR_DIR (COLOR_PAIR(2) | A_BOLD)
- #define ATTR_BOLDDIR (COLOR_PAIR(4) | A_BOLD)
-
- #define ATTR_REDBAR (COLOR_PAIR(1) | A_BOLD | A_ALTCHARSET)
- #define ATTR_DIMREDBAR (COLOR_PAIR(11) | A_DIM | A_ALTCHARSET)
-
- #define ATTR_PANEL (COLOR_PAIR(3) | A_BOLD)
- #define ATTR_PANELTEXT (COLOR_PAIR(9) | A_BOLD)
-
- #define ATTR_PANEL2 (COLOR_PAIR(8) | A_BOLD)
-
- #define ATTR_PANELBOX (COLOR_PAIR(5) | A_BOLD)
- #define ATTR_PANELBOXDIM (COLOR_PAIR(10))
- #define ATTR_PANELBOX2 (COLOR_PAIR(6) | A_BOLD)
-
- WINDOW *swin;
-
- int swin_LINES;
-
- extern struct mod_info M;
- extern struct options opt;
- extern int nr_visible_voices;
- extern char loaded;
-
- extern int nr_songs, nr_files, nr_dirs;
-
- inline void wsetcol(WINDOW *w, chtype col)
- {
- wattrset(w, col);
- }
-
- inline void setcol(chtype col)
- {
- attrset(col);
- }
-
- void init_screen(void)
- {
- if(!opt.interactive)
- return;
-
- initscr();
-
- #ifdef NCURSES_CHECK_FOR_COLOR
- if(!has_colors())
- error("No colour support on this terminal\n");
- #endif
- if(LINES < 19)
- error("You have to have at least 19 lines to run this program.\n");
-
- swin_LINES=MIN(opt.max_lines, LINES-16-2);
-
- swin=newwin(swin_LINES, COLS, 17, 0);
- setup_color_mode();
- cbreak();
- noecho();
- scrollok(stdscr, FALSE);
- leaveok(stdscr, TRUE);
- leaveok(swin, TRUE);
- keypad(stdscr, TRUE);
- curs_set(0); /* Turn the cursor off */
- }
-
-
- void cleanup_screen(void)
- {
- if(!opt.interactive)
- return;
-
- delwin(swin);
- keypad(stdscr, FALSE);
- setcol(COLOR_PAIR(0));
- clear();
- refresh();
- curs_set(1); /* Make cursor visible again */
- endwin();
- }
-
-
- void draw_screen()
- {
- int i;
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_LINE);
- clear();
- refresh();
- wsetcol(swin, ATTR_LINE);
- wclear(swin);
- wrefresh(swin);
-
- setcol(ATTR_PANEL);
- for(i=0; i < 16; ++i)
- mvaddstr(i, 0, " "
- " ");
-
- mvaddstr(1, 1, "Status "
- "Type MOD Songpos / Speed");
- mvaddstr(2, 1, " "
- "Voices 16 Pattern / Tempo");
- mvaddstr(3, 1, "Song "
- "Samples 16 Line /");
- mvaddstr(5, 1, "File "
- "Size Time :");
-
- refresh();
-
- print_pos(-1,0);
- print_speed(-1,0);
- print_songinfo(-1,0,0,0,0,0);
- print_time(-1);
-
- print_minihelp();
-
- setcol(ATTR_PANEL);
- mvaddstr(7, 2, "# Samplename Size Volume Looped Tune Bits "
- "Type");
- refresh();
-
- print_songname(" ");
- print_filename(-1);
- print_samples(-1);
-
- print_channelnumbers(0);
- print_status("");
-
- setcol(ATTR_REDBAR);
- mvaddstr(swin_LINES+18-1, 0, " Mod version 0.61 - "
- "(C) 1994 Mikael Nordqvist ");
- refresh();
- }
-
-
- void clear_screen(void)
- {
- if(!opt.interactive)
- return;
-
- wsetcol(swin, COLOR_PAIR(7));
- werase(swin);
- wrefresh(swin);
- }
-
-
- void print_channelnumbers(int nr)
- {
- char buf[81];
- int i, x, y, delta, actualvoices;
- struct event dummy={0,0,0,0,0,0};
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_REDBAR);
- if(!loaded) {
- mvprintw(16, 0, fill_string("", 80));
- }
- else {
- delta=print_event(buf, &dummy); /* to find out characters/channel */
- actualvoices=MIN(nr_visible_voices, M.nr_voices);
- mvprintw(16, 0, " %s %s", (nr ? "<<" : " "),
- fill_string("", (80-5-4-actualvoices*delta)/2+(delta-2)/2));
- refresh();
-
- for(i=nr; i < nr+actualvoices-1; ++i) {
- if(opt.active_voices & (1<<i))
- setcol(ATTR_REDBAR);
- else
- setcol(ATTR_DIMREDBAR);
- printw("%2d%s", i+1, fill_string("", delta-2));
- refresh();
- }
- if(opt.active_voices & (1<<i))
- setcol(ATTR_REDBAR);
- else
- setcol(ATTR_DIMREDBAR);
-
- getyx(stdscr, y, x);
- printw("%2d%s", i+1, fill_string("", 80-1-2-x-4));
- refresh();
- setcol(ATTR_REDBAR);
- printw("%s ", (i < M.nr_voices-1 ? ">>" : " "));
- }
- refresh();
- }
-
-
- void print_selectingbar(void)
- {
- if(!opt.interactive)
- return;
-
- setcol(ATTR_REDBAR);
-
- mvprintw(16, 0, " Size Filename "
- " Directories: %3d Files: %4d ",
- nr_dirs, nr_files-nr_dirs);
- refresh();
- }
-
-
- void print_songname(char *n)
- {
- char noname[]="<no name>";
-
- if(!opt.interactive)
- return;
-
- if(n && !strlen(n))
- n=noname;
- setcol(ATTR_PANELBOX);
- mvaddstr(3, 6, fill_string(n, 27));
- refresh();
- }
-
-
- void print_filename(int s)
- {
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELBOX);
- mvaddstr(5, 6, fill_string((s == -1 ? "" : get_modulename(s)), 27));
- refresh();
- }
-
-
- void print_status(char *s)
- {
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELBOX);
- mvaddstr(1, 8, fill_string(s ? s : "", 25));
- refresh();
- }
-
-
- void print_files(int n)
- {
- int i, f;
- int oldattr, newattr;
-
- if(!opt.interactive)
- return;
-
- f=n-swin_LINES/2;
- if(!(swin_LINES%2))
- f++;
-
- oldattr=ATTR_FILE;
- wsetcol(swin, oldattr);
- for(i=0; i < swin_LINES; ++i, ++f) {
- if(f < 0 || f >= nr_files) {
- wmove(swin, i, 0);
- }
- else {
- if(f != n) {
- if(is_dir(f))
- newattr=ATTR_DIR;
- else
- newattr=ATTR_FILE;
- }
- else {
- if(is_dir(f))
- newattr=ATTR_BOLDDIR;
- else
- newattr=ATTR_BOLDFILE;
- }
- if(newattr != oldattr) {
- wrefresh(swin);
- wsetcol(swin, newattr);
- oldattr=newattr;
- }
- mvwaddstr(swin, i, 0, get_filestring(f));
- }
- wclrtoeol(swin);
- }
- wrefresh(swin);
- }
-
-
- void print_samples(int n)
- {
- int i;
- struct sample_info *s;
- #ifdef FLUSH_INPUT
- char buf[80];
- #endif
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELBOX);
- for(i=0; i < 8; ++i) {
- if(n == -1)
- mvwaddstr(stdscr, 8+i, 1,
- " "
- " ");
- else {
- s=&M.sample[n];
- if(s->length > 4)
- setcol(ATTR_PANELBOX);
- else
- setcol(ATTR_PANELBOXDIM);
-
- mvwprintw(stdscr, 8+i, 1,
- "%2d %s %6d %3d %s %+2d %2s %-6s",
- n, fill_string((M.format == MODFORMAT_ULT ? s->dosname :
- s->name), 22),
- s->length, s->volume,
- (s->looped ?
- (s->looped == LOOP_BIDIR ? "BIDI" : "Yes ") : " "),
- s->finetune, (s->bits_16 ? "16" : " 8"),
- s->length > 4 ? "mono" : "unused");
- }
- refresh();
- if(n != -1 && ++n > M.nr_samples)
- n=-1;
- }
- #ifdef FLUSH_INPUT
- read(STDIN_FILENO, buf, 80); /* Flush input (for slow CPU's) */
- #endif
- }
-
- char *help_pages[6][9]= {
- {
- " Welcome!! ",
- " ",
- " I hope you ",
- " will enjoy ",
- " using mod! ",
- " ",
- "F1 and h will",
- "let you flip ",
- " help pages. "
- },
- {
- " Always: ",
- " ",
- " q Quit ",
- " h Help ",
- " l Load mode",
- " on/off ",
- "+/- Volume ",
- " m Mute ",
- " on/off "
- },
- {
- "In load-mode:",
- " ",
- "n/p Next/prev",
- " file ",
- "N/P Next/prev",
- " file page",
- " u Parent ",
- " directory",
- "ENT Select "
- },
- {
- " Otherwise: ",
- " ",
- "f/b FF/RW ",
- " r Restart ",
- " ",
- "n/p Next/prev",
- " song ",
- " ",
- "ENT Play/Stop"
- },
- {
- " Otherwise: ",
- " ",
- " s Scrolling",
- " on/off ",
- " v Voice ",
- " detail ",
- "0-9 Toggle ",
- " voices ",
- " on/off "
- },
- {
- " There are ",
- " more keys ",
- " available. ",
- "(up/down etc)",
- " ",
- "Read The Fine",
- " Manual for ",
- " more ",
- " information."
- }
- };
-
- void print_minihelp(void)
- {
- static int cur_page=0;
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_REDBAR);
- move(5, 65);
- vline(ACS_VLINE, 9);
- move(5, 79);
- vline(ACS_VLINE, 9);
-
- move(4, 65);
- addch(ACS_ULCORNER);
- hline(ACS_HLINE, 13);
- move(4, 79);
- addch(ACS_URCORNER);
-
- move(14, 65);
- addch(ACS_LLCORNER);
- hline(ACS_HLINE, 13);
- move(14, 79);
- addch(ACS_LRCORNER);
-
- mvaddstr(5, 66, help_pages[cur_page][0]);
- mvaddstr(6, 66, help_pages[cur_page][1]);
- mvaddstr(7, 66, help_pages[cur_page][2]);
- mvaddstr(8, 66, help_pages[cur_page][3]);
- mvaddstr(9, 66, help_pages[cur_page][4]);
- mvaddstr(10, 66, help_pages[cur_page][5]);
- mvaddstr(11, 66, help_pages[cur_page][6]);
- mvaddstr(12, 66, help_pages[cur_page][7]);
- mvaddstr(13, 66, help_pages[cur_page][8]);
- refresh();
- cur_page=(cur_page+1)%6;
- }
-
- #ifdef DISPLAY_SEQ_IO_Q
- #include <sys/ioctl.h>
- #include <sys/soundcard.h>
-
- extern int seqfd;
- #endif
-
- void print_pos(int pos, int line)
- {
- int i;
- #ifdef DISPLAY_SEQ_IO_Q
- int o;
- char buf[80];
- #endif
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELTEXT);
- if(pos != -1) {
- mvwprintw(stdscr, 1, 56, "%3d", pos);
- mvwprintw(stdscr, 2, 56, "%3d", M.patterntable[pos]);
- mvwprintw(stdscr, 3, 56, "%3d", line);
- }
- else {
- for(i=1; i <= 3; ++i)
- mvwprintw(stdscr, i, 56, " ");
- }
- refresh();
-
- #ifdef DISPLAY_SEQ_IO_Q
- ioctl(seqfd, SNDCTL_SEQ_GETINCOUNT, &i);
- ioctl(seqfd, SNDCTL_SEQ_GETOUTCOUNT, &o);
- sprintf(buf, "I/O: %d/%d", i, 1024-o);
- print_status(buf);
- #endif
- }
-
- void print_speed(int spd, int tempo)
- {
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELTEXT);
- if(spd != -1) {
- mvwprintw(stdscr, 1, 71, "%3d", spd);
- mvwprintw(stdscr, 2, 71, "%3d", tempo);
- }
- else {
- mvwprintw(stdscr, 1, 71, " ");
- mvwprintw(stdscr, 2, 71, " ");
- }
- refresh();
- }
-
-
- void print_songinfo(int v, int samp, char *type, int sz, int songlen, int pat)
- {
- int i;
-
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELTEXT);
-
- if(v != -1) {
- mvwprintw(stdscr, 1, 43, "%3s", type);
- mvwprintw(stdscr, 2, 44, "%2d", v);
- mvwprintw(stdscr, 3, 44, "%2d", samp);
- mvwprintw(stdscr, 5, 41, "%4dk", sz/1024);
-
- mvwprintw(stdscr, 1, 60, "%3d", songlen-1);
- mvwprintw(stdscr, 2, 60, "%3d", pat-1);
- mvwprintw(stdscr, 3, 60, " 63");
- }
- else {
- for(i=1; i <= 3; ++i)
- mvwprintw(stdscr, i, 43, " ");
- mvwprintw(stdscr, 5, 41, " ");
- for(i=1; i <= 3; ++i)
- mvwprintw(stdscr, i, 60, " ");
- }
- refresh();
- }
-
-
- void print_time(int t)
- {
- if(!opt.interactive)
- return;
-
- setcol(ATTR_PANELTEXT);
- if(t != -1) {
- mvwprintw(stdscr, 5, 57, "%3d", t/60);
- mvwprintw(stdscr, 5, 61, "%02d", t%60);
- }
- else {
- mvwprintw(stdscr, 5, 57, " ");
- mvwprintw(stdscr, 5, 61, " ");
- }
- refresh();
- }
-
-
- void clear_all_info(void)
- {
- if(!opt.interactive)
- return;
-
- print_samples(-1);
- print_status("");
- print_songname(" ");
- print_filename(-1);
-
- print_pos(-1,0);
- print_speed(-1,0);
- print_songinfo(-1,0,0,0,0,0);
- print_time(-1);
- }
-
-
- void print_line(int songpos, int line, int voice)
- {
- static char tmpbuf[256]={" "
- " "};
- char *buf;
- int pos, pat, step, v, l, i;
- char midline[81];
- int mid_i=0; /* Remove warning */
-
- if(!opt.interactive)
- return;
-
- scrollok(swin, FALSE);
- wsetcol(swin, ATTR_LINE);
- pat=M.patterntable[songpos];
-
- l=line-swin_LINES/2;
- if(!(swin_LINES%2))
- l++;
-
- buf=&tmpbuf[80];
- for(i=0; i < swin_LINES; ++i, ++l) {
- wmove(swin, i, 0);
- if(l < 0 || l > 63) {
- wclrtoeol(swin);
- }
- else {
- sprintf(buf, "%02d ", l);
- pos=4;
- for(v=voice; v < M.nr_voices && v < voice+nr_visible_voices; ++v) {
- step=print_event(&buf[pos], GET_EVENT_PTR(v, pat, l));
- pos+=step;
- }
- sprintf(&buf[pos], "| %02d", l);
- pos+=5;
-
- if(l != line) {
- waddstr(swin, &buf[(pos-80)/2]);
- wclrtoeol(swin);
- }
- else {
- strcpy(midline, &buf[(pos-80)/2]);
- mid_i=i;
- }
- }
- }
- wrefresh(swin);
- wsetcol(swin, ATTR_BOLDLINE);
- wmove(swin, mid_i, 0);
- waddstr(swin, midline);
- wclrtoeol(swin);
- wrefresh(swin);
- }
-
- extern char *notenames[NR_OCTAVES*12+1];
- extern char *effectnames[NR_EFX];
- extern char *shorteffectnames[NR_EFX];
-
- int print_event(char *buf, struct event *n)
- {
- unsigned char note=n->note;
-
- if(note == NOTE_OFF)
- note=12*8+BASE_NOTE; /* Last of the named notes */
- else {
- if(note && M.format != MODFORMAT_S3M)
- note-=2*12;
- }
-
- if(nr_visible_voices == 17) { /* Only notes */
- sprintf(buf, "|%s",
- (note ? notenames[note-BASE_NOTE] : " "));
- return 4;
- }
- else if(nr_visible_voices == 9) { /* Notes + instruments */
- sprintf(buf, "|%s ",
- (note ? notenames[note-BASE_NOTE] : " "));
-
- if(n->sample)
- sprintf(buf+5, "%2d", n->sample);
- else
- strcpy(buf+5, " ");
- return 7;
- }
- else { /* All of it (unless there are two effects) */
- sprintf(buf, "| %s ",
- (note ? notenames[note-BASE_NOTE] : " "));
-
- if(n->sample)
- sprintf(buf+6, "%2d ", n->sample);
- else
- strcpy(buf+6, " ");
-
- /* Check if there are one or two effects. If there are two we just
- * display the effects without the arguments.
- */
- if(M.format != MODFORMAT_S3M && ((!n->effect && n->arg) || n->effect)
- && ((!n->effect2 && n->arg2) || n->effect2)) {
-
- /* Two effects */
- sprintf(buf+9, "%s+%s ", shorteffectnames[n->effect],
- shorteffectnames[n->effect2]);
- }
- else {
- /* Only one (or no) effect */
- if((!n->effect && n->arg) || n->effect)
- sprintf(buf+9, "%s %02X ", effectnames[n->effect], n->arg);
- else if(!M.format == MODFORMAT_S3M &&
- ((!n->effect2 && n->arg2) || n->effect2))
- sprintf(buf+9, "%s %02X ", effectnames[n->effect2], n->arg2);
- else
- strcpy(buf+9, " ");
- }
- return 17;
- }
- }
-
- void setup_color_mode(void)
- {
- start_color();
- init_pair(1, COLOR_YELLOW, COLOR_RED);
- init_pair(2, COLOR_BLUE, COLOR_BLACK);
- init_pair(3, COLOR_WHITE, COLOR_CYAN);
- init_pair(4, COLOR_CYAN, COLOR_BLACK);
- init_pair(5, COLOR_YELLOW, COLOR_BLUE);
- init_pair(6, COLOR_YELLOW, COLOR_MAGENTA);
- init_pair(7, COLOR_WHITE, COLOR_BLACK);
- init_pair(8, COLOR_WHITE, COLOR_WHITE);
- init_pair(9, COLOR_BLUE, COLOR_CYAN);
- init_pair(10, COLOR_WHITE, COLOR_BLUE);
- init_pair(11, COLOR_WHITE, COLOR_RED);
- }
-