home *** CD-ROM | disk | FTP | other *** search
- /* MikMod example player
- (c) 1998 Miodrag Vallat and others - see file AUTHORS for complete list
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /*==============================================================================
-
- $Id: display.c,v 1.31 1998/12/07 06:01:23 miod Exp $
-
- Ncurses display section of mikmod - bare unix version.
-
- Should deal with all the quiet options and refresh() after ncurses calls,
- so just call these functions direct wherever needed.
-
- ==============================================================================*/
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #if defined(__OS2__)||defined(__EMX__)
- #define INCL_VIO
- #include <os2.h>
- #else
- #ifdef HAVE_SYS_IOCTL_H
- #include <sys/ioctl.h>
- #endif
- #ifdef HAVE_NCURSES_H
- #include <ncurses.h>
- #else
- #include <curses.h>
- #endif
- #endif
-
- #include <mikmod.h>
- #include "player.h"
-
- /*========== Display layout constants */
-
- /* maximum screen width we handle */
- #define MAXWIDTH (80)
- /* half width */
- #define HALFWIDTH (MAXWIDTH>>1)
- /* format used for message/banner lines */
- #define FMT_FULLWIDTH "%-80.80s"
- /* format used for sample/instrument lines - the number should be HALFWIDTH-4 */
- #define FMT_HALFWIDTH "%-36.36s"
-
- /*========== Variables */
-
- extern int quiet,semiquiet;
- extern MODULE *mf;
-
- int curses_on=0;
- int firstinst,dispsamp=1;
-
- /* help panels */
- static char keyhelp1[]=keyhelptext1;
- static char keyhelp2[]=keyhelptext2;
-
- /* screen size */
- int winy=0; /* not static since used by mikmod.c */
- static int winx=0;
- #if !defined(__OS2__)&&!defined(__EMX__)
- static int resize=0;
- #endif
-
- /* text creation buffer */
- static char storage[MAXWIDTH+1];
-
- #if defined(__OS2__)||defined(__EMX__)
- static HVIO hvio=0;
- static VIOCURSORINFO viocursorinfo;
- static BYTE clearscreen[2]={0xff,0x0f};
- #endif
-
- /*========== Display routines */
-
- /* old AIX curses are very limited */
- #if defined(AIX) && !defined(mvaddnstr)
- #define mvaddnstr(y,x,str,cnt) mvaddstr(y,x,str)
- #endif
-
- /* HP-UX curses macros don't work with every cpp */
- #if defined __hpux
- void getmaxyx_hpux(WINDOW* win,int* y,int *x)
- {
- *y=__getmaxy(win);
- *x=__getmaxx(win);
- }
- #define getmaxyx(win,y,x) getmaxyx_hpux((win),&(y),&(x))
- #endif
-
- void display_all(void);
-
- #if !defined(__OS2__)&&!defined(__EMX__)
- /* handler for terminal resize events */
- RETSIGTYPE sigwinch_handler(int signum)
- {
- /* schedule a resizeterm() */
- resize=1;
-
- signal(SIGWINCH,sigwinch_handler);
- }
- #endif
-
- #if defined(__OS2__)||defined(__EMX__)
-
- void clear(void)
- {
- /* overwrite entire screen with 0s */
- VioWrtNCell(clearscreen,winy*winx,0,0,hvio);
- }
- #define mvaddnstr(y,x,text,width) VioWrtCharStr(text,strlen(text),y,x,hvio)
- #define refresh()
-
- /* initialize screen */
- void init_display(void)
- {
- VIOCURSORINFO tmpviocursorinfo;
- VIOMODEINFO tmpviomodeinfo;
-
- if(quiet) return;
-
- /* get old cursor */
- VioGetCurType(&viocursorinfo,hvio);
- /* set new cursor */
- tmpviocursorinfo.yStart=0;
- tmpviocursorinfo.cEnd=0;
- tmpviocursorinfo.cx=viocursorinfo.cx;
- tmpviocursorinfo.attr=-1; /* hide cursor */
- VioSetCurType(&viocursorinfo,hvio);
- /* get video mode info */
- tmpviomodeinfo.cb=sizeof(tmpviomodeinfo);
- VioGetMode(&tmpviomodeinfo,hvio);
- winy=tmpviomodeinfo.row;winx=tmpviomodeinfo.col;
-
- clear();
- VioSetCurPos(winy-1,0,hvio);
-
- curses_on=1;
- }
-
- void mikmod_clrtoeol(int y,int x)
- {
- VioWrtNCell(clearscreen,winx-x,y,x,hvio);
- }
-
- void mikmod_clrtobot(int y,int x)
- {
- VioWrtNCell(clearscreen,winx*(winy-y)+winx-x,y,x,hvio);
- }
-
- #else
-
- /* initialize curses */
- void init_curses(void)
- {
- initscr();
- cbreak();
- noecho();
- nonl();
- nodelay(stdscr,TRUE);
- #if !defined(AIX) || defined(NCURSES_VERSION)
- timeout(0);
- #endif
- keypad(stdscr,TRUE);
- curses_on=1;
- }
-
- /* initialize screen */
- void init_display(void)
- {
- if(quiet) return;
-
- init_curses();
- #if defined(AIX) && !defined(NCURSES_VERSION)
- winy=LINES;winx=COLS;
- #else
- getmaxyx(stdscr,winy,winx);
- #endif
- signal(SIGWINCH,sigwinch_handler);
- }
-
- void mikmod_clrtoeol(int y,int x)
- {
- move(y,x);clrtoeol();
- }
-
- void mikmod_clrtobot(int y,int x)
- {
- move(y,x);clrtobot();
- }
-
- #endif
-
- /* first line : MikMod version */
- void display_version(void)
- {
- if(quiet) return;
-
- /* we always use display_version first, so clear call is OK here... */
- clear();
-
- mvaddnstr(0,0,mikversion,winx);
- refresh();
- }
-
- /* display a banner/message from line skip, at position origin
- returns updated skip value if it is out of bounds and would prevent the
- message from being seen. */
- int display_banner(char* banner,int origin,int skip)
- {
- char *foo=banner,str[MAXWIDTH+1];
- int i,n,t;
-
- /* count message lines */
- for(t=1;*foo;t++) {
- while((*foo!='\r')&&(*foo!='\n')&&(*foo))
- foo++;
- if (*foo) foo++;
- }
- /* update skip value */
- if (skip+winy-origin+1>=t) skip=t-winy+origin-1;
- if (skip<0) skip=0;
- /* display lines */
- foo=banner;
- for(i=0;i<t;i++) {
- for(n=0;(*foo!='\r')&&(*foo!='\n')&&(*foo);foo++) {
- str[n]=*foo;
- if(n<MAXWIDTH) n++;
- }
- foo++;
- if (i>=skip) {
- if (n) {
- str[n]=0;
- sprintf(storage,FMT_FULLWIDTH,str);
- mvaddnstr(i-skip+origin,0,storage,winx);
- } else
- mikmod_clrtoeol(i-skip+origin,0);
- }
- }
- /* clear remaining part of the screen */
- mikmod_clrtobot(t-skip+origin,0);
-
- return skip;
- }
-
- /* displays the "paused" banner */
- void display_pausebanner(void)
- {
- if(quiet) return;
- clear();
- mvaddnstr(0,0,mikversion,winx);
- display_banner(pausebanner,1,0);
- refresh();
- }
-
- /* display the "extracting" banner */
- void display_extractbanner(void)
- {
- if(quiet) return;
- clear();
- mvaddnstr(0,0,mikversion,winx);
- display_banner(extractbanner,1,0);
- refresh();
- }
-
- /* display the "loading" banner */
- void display_loadbanner(void)
- {
- if(quiet) return;
- clear();
- mvaddnstr(0,0,mikversion,winx);
- display_banner(loadbanner,1,0);
- refresh();
- firstinst=0;
- }
-
- /* second line : driver settings */
- void display_driver(void)
- {
- if((quiet)||(winy<=1)) return;
- if (md_reverb)
- #if defined(__OS2__)||defined(__EMX__)
- sprintf(storage,"%s: %d bit %s %s, %u Hz, reverb: %u",
- #else
- sprintf(storage,"%s: %d bit %s %s, %u Hz, reverb: %u\n",
- #endif
- md_driver->Name,
- (md_mode&DMODE_16BITS) ? 16:8,
-
- (md_mode&DMODE_INTERP) ?
- (md_mode&DMODE_SURROUND?"interp. surround":"interpolated"):
- (md_mode&DMODE_SURROUND?"surround":"normal"),
-
- (md_mode&DMODE_STEREO) ? "stereo":"mono",
- md_mixfreq, md_reverb);
- else
- #if defined(__OS2__)||defined(__EMX__)
- sprintf(storage,"%s: %d bit %s %s, %u Hz, no reverb",
- #else
- sprintf(storage,"%s: %d bit %s %s, %u Hz, no reverb\n",
- #endif
- md_driver->Name,
- (md_mode&DMODE_16BITS) ? 16:8,
-
- (md_mode&DMODE_INTERP) ?
- (md_mode&DMODE_SURROUND?"interp. surround":"interpolated"):
- (md_mode&DMODE_SURROUND?"surround":"normal"),
-
- (md_mode&DMODE_STEREO) ? "stereo":"mono",
- md_mixfreq);
- mvaddnstr(1,0,storage,winx);
- #if defined(__OS2__)||defined(__EMX__)
- mikmod_clrtoeol(1,strlen(storage));
- #endif
- refresh();
- }
-
- /* third line : filename */
- void display_file(void)
- {
- char filename[255];
- char arc[255];
-
- if((quiet)||(winy<=2)) return;
- PL_GetCurrent(&playlist,filename,arc);
- #if defined(__OS2__)||defined(__EMX__)
- sprintf(storage,"File: %.70s",filename);
- #else
- sprintf(storage,"File: %.70s\n",filename);
- #endif
- mvaddnstr(2,0,storage,winx);
- refresh();
- }
-
- /* fourth and fifth lines : module name and format */
- void display_name(void)
- {
- if((quiet)||(winy<=3)) return;
- #if defined(__OS2__)||defined(__EMX__)
- sprintf(storage,"Name: %.70s",mf->songname);
- #else
- sprintf(storage,"Name: %.70s\n",mf->songname);
- #endif
- mvaddnstr(3,0,storage,winx);
- #if defined(__OS2__)||defined(__EMX__)
- sprintf(storage,"Type: %s, Periods: %s, %s",
- #else
- sprintf(storage,"Type: %s, Periods: %s, %s\n",
- #endif
- mf->modtype,
- (mf->flags&UF_XMPERIODS) ? "XM type" : "mod type",
- (mf->flags&UF_LINEAR) ? "linear" : "log");
- mvaddnstr(4,0,storage,winx);
- refresh();
- }
-
- /* sixth line : player status */
- void display_status(void)
- {
- if(quiet) return;
-
- #if !defined(__OS2__)&&!defined(__EMX__)
- /* if a resize was scheduled, do it now */
- if(resize) {
- #if (NCURSES_VERSION_MAJOR >= 4) && defined(TIOCGWINSZ)
- struct winsize ws;
-
- ws.ws_col=ws.ws_row=0;
- ioctl(0,TIOCGWINSZ,&ws);
- if(ws.ws_col && ws.ws_row)
- resizeterm(ws.ws_row,ws.ws_col);
- #else
- #ifndef NCURSES_VERSION
- endwin();
- init_curses();
- #endif
- #endif
- #if defined(AIX) && !defined(NCURSES_VERSION)
- winy=LINES;winx=COLS;
- #else
- getmaxyx(stdscr,winy,winx);
- #endif
- resize=0;
- display_all();
- }
- #endif
-
- if (winy<=5) return;
- if (mf->sngpos<mf->numpos) {
- #if defined(sun) && !defined(HAVE_NCURSES)
- /* Solaris curses has a nasty bug and will try to interpret the hexa
- digits generated by %02.2X, so we'll add these manually after... */
- sprintf(storage,"pat:%03d/%03d pos: spd:%2d bpm:%3d "
- "vol:%3d%% time:%2d:%02d",
- mf->sngpos,mf->numpos-1,mf->sngspd,mf->bpm,
- (mf->volume*100+64)>>7,(int)(((mf->sngtime>>10)/60)%60),
- (int)((mf->sngtime>>10)%60));
- #else
- sprintf(storage,"pat:%03d/%03d pos:%02.2X spd:%2d bpm:%3d "
- "vol:%3d%% time:%2d:%02d",
- mf->sngpos,mf->numpos-1,mf->patpos,mf->sngspd,mf->bpm,
- (mf->volume*100+64)>>7,(int)(((mf->sngtime>>10)/60)%60),
- (int)((mf->sngtime>>10)%60));
- #endif
- if (!semiquiet)
- strcat(storage," - press H for help");
- mvaddnstr(5,0,storage,winx);
- #if defined(sun) && !defined(HAVE_NCURSES)
- if (winx>17)
- mvaddch(5,17,((mf->patpos&0x0f)<=9)?'0'+(mf->patpos&0x0f):'A'+((mf->patpos&0x0f)-10));
- if (winx>16)
- mvaddch(5,16,((mf->patpos>>4)<=9)?'0'+(mf->patpos>>4):'A'+((mf->patpos>>4)-10));
- move(5,strlen(storage));
- #endif
- }
- refresh();
- }
-
- #if defined(__OS2__)||defined(__EMX__)
-
- /* exits curses */
- void exit_display(void)
- {
- if(quiet) return;
-
- clear();
- mvaddnstr(winy-2,0,mikversion,winx);
- /* restore old cursor */
- VioSetCurType(&viocursorinfo,hvio);
- VioSetCurPos(winy-1,0,hvio);
-
- curses_on=0;
- }
-
- #else
-
- /* exits curses */
- void exit_display(void)
- {
- if(quiet) return;
-
- signal(SIGWINCH,SIG_DFL);
- clear();
- mvaddnstr(winy-2,0,mikversion,winx);
- refresh();
- endwin();
- curses_on=0;
- }
-
- #endif
-
- /* seventh line to bottom of screen : information panel */
- void display_information(void)
- {
- int t,x;
- int count,semicount;
-
- if(quiet || semiquiet || (winy<=6)) return;
- if((dispsamp&2)&&(!mf->comment)) dispsamp^=2;
- if((dispsamp&1)&&(!mf->instruments)) dispsamp^=1;
- if((!(dispsamp&1))&&(!mf->samples)) dispsamp^=1;
- semicount=winy-6,count=semicount<<1;
-
- if (dispsamp&8) {
- /* bit 3 set : help panel 2 */
- display_banner(keyhelp2,6,0);
- } else
- if (dispsamp&4) {
- /* bit 2 set : help panel 1 */
- display_banner(keyhelp1,6,0);
- } else
- if (dispsamp&2) {
- /* bit 1 set : module comments */
- firstinst=display_banner(mf->comment,6,firstinst);
- } else
- if (dispsamp&1) {
- /* bit 0 set : samples */
- mikmod_clrtobot(6,0);
- if(firstinst>=mf->numins-count) firstinst=mf->numins-count;
- if(firstinst<0) firstinst=0;
- if ((mf->numins>semicount)&&(mf->numins<count)) {
- semicount=(mf->numins+1)>>1;count=semicount<<1;
- }
- for(t=firstinst;t<mf->numins && t<(count+firstinst);t++) {
- sprintf(storage,"%3i " FMT_HALFWIDTH,t,
- mf->instruments[t].insname?mf->instruments[t].insname:"");
- x=((t-firstinst)<semicount)?0:HALFWIDTH;
- if(x<winx)
- mvaddnstr((t-firstinst)%semicount+6,x,storage,winx-x);
- }
- } else {
- /* bit 0 unset : instruments */
- mikmod_clrtobot(6,0);
- if(firstinst>=mf->numsmp-count) firstinst=mf->numsmp-count;
- if(firstinst<0) firstinst=0;
- if ((mf->numsmp>semicount)&&(mf->numsmp<count)) {
- semicount=(mf->numsmp+1)>>1;count=semicount<<1;
- }
- for(t=firstinst;t<mf->numsmp && t<(count+firstinst);t++) {
- sprintf(storage,"%3i " FMT_HALFWIDTH,t,
- mf->samples[t].samplename?mf->samples[t].samplename:"");
- x=((t-firstinst)<semicount)?0:HALFWIDTH;
- if(x<winx)
- mvaddnstr((t-firstinst)%semicount+6,x,storage,winx-x);
- }
- }
- refresh();
- }
-
- /* redisplays the whole screen */
- void display_all(void)
- {
- if(quiet) return;
-
- display_version();
- display_driver();
- display_file();
- display_name();
- display_status();
- display_information();
- }
-