home *** CD-ROM | disk | FTP | other *** search
/ Mega A/V / mega_av.zip / mega_av / SOUNDUTL / MUSIQUE.ZIP / SOURCE.ZIP / WINDOW.C < prev    next >
C/C++ Source or Header  |  1991-09-06  |  33KB  |  948 lines

  1. /* Warning! This C source contains extended characters! */
  2.  
  3. #include <dos.h>
  4. #include <bios.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <musique.h>
  8. #include <window.e>
  9.  
  10. int coloroutline;
  11. int colortitle;
  12. /* colors of unpicked/picked menu items */
  13. int coloritem;
  14. int colorpicked;
  15.  
  16. /* background color of keyboard cursor */
  17. int colorcurrent;
  18. /* border color and background color of screen */
  19. int colorborder;
  20.  
  21. void mycputs(PARAMETERTYPE *parameter, int x, int y, char text[], int color)
  22. /* Turbo-C doesn't like extended or non-text modes */
  23. /* Turbo-C scrolls the screen too much (lower-right corner) */
  24. /* prints a string on the screen in the desired color */
  25. /* no wrap around ever performed */
  26. {
  27.   union REGS regs;
  28.   int position;
  29.   char c;
  30.  
  31.   position=0;
  32.   x--; y--;
  33.   if (parameter->rawvideo) {
  34.     x<<=1;
  35.     x+=(y*parameter->maxcolumn)<<1;
  36.     while ((c=text[position++])!='\0') {
  37.       pokeb((unsigned)parameter->videosegment,(unsigned)x++,(int)c);
  38.       pokeb((unsigned)parameter->videosegment,(unsigned)x++,color);
  39.     }
  40.   }
  41.   else 
  42.     while ((c=text[position++])!='\0') {
  43.       regs.h.ah=(unsigned)'\x2'; /* set cursor position */
  44.       regs.h.bh=(unsigned)'\x0';
  45.       regs.h.dl=(unsigned char)x++;
  46.       regs.h.dh=(unsigned char)y;
  47.       int86(0x10,®s,®s);
  48.       regs.h.ah=(unsigned)'\x9'; /* print one character */
  49.       regs.h.bh=(unsigned)'\x0';
  50.       regs.x.cx=(unsigned)0x1;
  51.       regs.h.bl=(unsigned char)color;
  52.       regs.h.al=(unsigned)c;
  53.       int86(0x10,®s,®s);
  54.     }
  55. }
  56.  
  57. void myscrollup(PARAMETERTYPE *parameter)
  58. /* scrolls up one line */
  59. {
  60.   union REGS regs;
  61.   int x,y,source,target,RAM;
  62.  
  63.   if (parameter->rawvideo) {
  64.     target=(parameter->maxcolumn<<2)+4;
  65.     source=target+(parameter->maxcolumn<<1);
  66.     for (y=2 ; y<=parameter->maxline-4 ; y++) {
  67.       for (x=2 ; x<=parameter->maxcolumn-3 ; x++) {
  68.         RAM=peek((unsigned)parameter->videosegment,(unsigned)source);
  69.         poke((unsigned)parameter->videosegment,(unsigned)target,RAM);
  70.         source+=2; target+=2;
  71.       }  
  72.       source+=8; target+=8;
  73.     }
  74.     for (x=2 ; x<=parameter->maxcolumn-3 ; x++) {
  75.       pokeb((unsigned)parameter->videosegment,(unsigned)target,' ');
  76.       target+=2;
  77.     }
  78.   }
  79.   else {
  80.     regs.x.ax=(unsigned)0x601;
  81.     regs.h.bh=(unsigned char)colorborder;
  82.     regs.x.cx=(unsigned)0x202;
  83.     regs.h.dl=(unsigned char)(parameter->maxcolumn-3);
  84.     regs.h.dh=(unsigned char)(parameter->maxline-3);
  85.     int86(0x10,®s,®s);
  86.     /* enables high intensity background */
  87.     highbackground();
  88.   }
  89. }
  90.  
  91. void myscrolldown(PARAMETERTYPE *parameter)
  92. /* scrolls down one line */
  93. {
  94.   union REGS regs;
  95.   int x,y,source,target,RAM;
  96.  
  97.   if (parameter->rawvideo) {
  98.     target=(((parameter->maxline-2)*parameter->maxcolumn)<<1)-6;
  99.     source=target-(parameter->maxcolumn<<1);
  100.     for (y=parameter->maxline-3 ; y>=3 ; y--) {
  101.       for (x=2 ; x<=parameter->maxcolumn-3 ; x++) {
  102.         RAM=peek((unsigned)parameter->videosegment,(unsigned)source);
  103.         poke((unsigned)parameter->videosegment,(unsigned)target,RAM);
  104.         source-=2; target-=2;
  105.       }  
  106.       source-=8; target-=8;
  107.     }
  108.     for (x=2 ; x<=parameter->maxcolumn-3 ; x++) {
  109.       pokeb((unsigned)parameter->videosegment,(unsigned)target,' ');
  110.       target-=2;
  111.     }  
  112.   }
  113.   else {
  114.     regs.x.ax=(unsigned)0x701;
  115.     regs.h.bh=(unsigned char)colorborder;
  116.     regs.x.cx=(unsigned)0x202;
  117.     regs.h.dl=(unsigned char)(parameter->maxcolumn-3);
  118.     regs.h.dh=(unsigned char)(parameter->maxline-3);
  119.     int86(0x10,®s,®s);
  120.     /* enables high intensity background */
  121.     highbackground();
  122.   }
  123. }
  124.  
  125. void movecursor(PARAMETERTYPE *parameter)
  126. /* moves the cursor out of the way one line too low */
  127. {
  128.   union REGS regs;
  129.  
  130.   regs.h.ah=(unsigned)'\x2';
  131.   regs.h.bh=(unsigned)'\x0';
  132.   regs.h.dl=(unsigned)'\x0';
  133.   regs.h.dh=(unsigned char)parameter->maxline;
  134.   int86(0x10,®s,®s);
  135. }
  136.  
  137. void printoutline(PARAMETERTYPE *parameter)
  138. /* prints a frame around the screen and the title */
  139. /* leaves cursor around */
  140. {
  141.   int column,line;
  142.  
  143.   mycputs(parameter,1,1,"┌",coloroutline|colorborder);
  144.   for (column=2 ; column<parameter->maxcolumn ; column++)
  145.     mycputs(parameter,column,1,"─",coloroutline|colorborder);
  146.   mycputs(parameter,parameter->maxcolumn,1,"┐",coloroutline|colorborder);
  147.   for (line=2 ; line<parameter->maxline ; line++) {
  148.     mycputs(parameter,1,line,"│",coloroutline|colorborder);
  149.     mycputs(parameter,parameter->maxcolumn,line,"│",coloroutline|colorborder);
  150.   }
  151.   mycputs(parameter,1,parameter->maxline,"└",coloroutline|colorborder);
  152.   for (column=2 ; column<parameter->maxcolumn ; column++)
  153.     mycputs(parameter,column,parameter->maxline,"─",coloroutline|colorborder);
  154.   mycputs(parameter,parameter->maxcolumn,parameter->maxline,"┘",
  155.           coloroutline|colorborder);
  156.   switch (language) {
  157.     case FRENCH:column=(parameter->maxcolumn-strlen(FTITLE)+3)/2;
  158.                 mycputs(parameter,column,1,FTITLE,colortitle|colorborder);
  159.                 break;
  160.     case ENGLISH:column=(parameter->maxcolumn-strlen(ETITLE)+3)/2;
  161.                  mycputs(parameter,column,1,ETITLE,colortitle|colorborder);
  162.                  break;
  163.     case GERMAN:column=(parameter->maxcolumn-strlen(GTITLE)+3)/2;
  164.                 mycputs(parameter,column,1,GTITLE,colortitle|colorborder);
  165.                 break;
  166.   }
  167. }
  168.  
  169. void cleverwrapper(PARAMETERTYPE *parameter, int *wrapper, int *column)
  170. /* evens out menu item columns nicely */
  171. /* uses the modulo algorithm taken from the usual line drawing algorithm */
  172. {
  173.   while (*wrapper<parameter->leftcolumn) {
  174.     (*column)++;    
  175.     *wrapper+=parameter->bigcolumn+1;
  176.   }
  177.   *wrapper-=parameter->leftcolumn;
  178. }
  179.  
  180. void putitem(int column, int line, SONGTYPE *song, int color, 
  181.              PARAMETERTYPE *parameter)
  182. /* puts a menu item in the color desired */
  183. /* leaves cursor around */
  184. {
  185.   column++;
  186.   if (parameter->verbose) {
  187.     mycputs(parameter,column,line,song->diskname,color);
  188.     column+=DISKNAMELENGTH+1;
  189.     mycputs(parameter,column,line,song->score,color);
  190.     column+=SCORELENGTH+1;
  191.   }
  192.   if (parameter->verbose || parameter->DOS) {
  193.     mycputs(parameter,column,line,song->DOSname,color);
  194.     column+=DOSNAMELENGTH+1;
  195.   }
  196.   if (parameter->verbose || !parameter->DOS)
  197.     mycputs(parameter,column,line,song->songname,color);
  198. }
  199.  
  200. void getbig(SONGSTYPE *songs, PARAMETERTYPE *parameter, int *bcolumn, 
  201.             int *bline)
  202. /* finds the coordinates of the current song in the menu window */
  203. {
  204.   *bcolumn=(songs->songcurrent-1)/parameter->hugeline+1;
  205.   *bline=songs->songcurrent-songs->songcorner-
  206.          (*bcolumn-1)*parameter->hugeline+1;
  207. }
  208.  
  209. int getmouseptr(SONGSTYPE *songs, PARAMETERTYPE *parameter, 
  210.                 MOUSETYPE *mousedata)
  211. /* finds the closest song name to the mouse cursor */
  212. {
  213.   int oldcolumn,column,halfcolumn,wrapper;
  214.   int bline,bcolumn; 
  215.   int songlimit;
  216.   int mouseptr;
  217.  
  218.   bline=mousedata->y-2;
  219.   if (bline<1) bline=1;
  220.   else 
  221.     if (bline>parameter->bigline) bline=parameter->bigline;
  222.   column=3;
  223.   wrapper=0;
  224.   bcolumn=1;
  225.   cleverwrapper(parameter,&wrapper,&column);
  226.   column+=parameter->itemlength;
  227.   oldcolumn=column;
  228.   cleverwrapper(parameter,&wrapper,&column);
  229.   halfcolumn=(column+oldcolumn)/2;
  230.   while (halfcolumn<=mousedata->x) {
  231.     column+=parameter->itemlength;
  232.     oldcolumn=column;
  233.     cleverwrapper(parameter,&wrapper,&column);
  234.     halfcolumn=(column+oldcolumn)/2;
  235.     bcolumn++;
  236.   }
  237.   if (bcolumn>parameter->bigcolumn) bcolumn=parameter->bigcolumn;
  238.   songlimit=bcolumn*parameter->hugeline;
  239.   mouseptr=songs->songcorner+(bcolumn-1)*parameter->hugeline+bline-1;
  240.   if (mouseptr>songlimit) mouseptr=songlimit;
  241.   if (mouseptr>songs->songnumber) mouseptr=songs->songnumber;
  242.   return(mouseptr);
  243. }
  244.  
  245. void putcurrent(SONGSTYPE *songs, PARAMETERTYPE *parameter, int color)
  246. /* puts the current song in the color desired */
  247. /* leaves cursor around */
  248. {
  249.   int line,column; /* screen coordinates */
  250.   int wrapper; /* used for clever column spacing */
  251.   int bline,bcolumn;
  252.  
  253.   getbig(songs,parameter,&bcolumn,&bline);
  254.   line=bline+2;
  255.   column=3;
  256.   wrapper=0;
  257.   cleverwrapper(parameter,&wrapper,&column);
  258.   while (--bcolumn>0) {
  259.     column+=parameter->itemlength;
  260.     cleverwrapper(parameter,&wrapper,&column);
  261.   }
  262.   putitem(column,line,&(songs->song[songs->songcurrent]),color,parameter);
  263. }
  264.  
  265. void unputcurrent(SONGSTYPE *songs, PARAMETERTYPE *parameter)
  266. /* unputs the current song */
  267. /* leaves cursor around */
  268. {
  269.   if (songs->song[songs->songcurrent].picked!=0) 
  270.     putcurrent(songs,parameter,colorpicked|colorborder);
  271.   else
  272.     putcurrent(songs,parameter,coloritem|colorborder);
  273. }
  274.  
  275. void changecurrent(SONGSTYPE *songs, PARAMETERTYPE *parameter, 
  276.                    MOUSETYPE *mousedata, int songptr)
  277. /* changes the current song and updates the menu window */
  278. /* moves away cursor */
  279. {
  280.   int mouseptr,intheway;
  281.  
  282.   if (songs->songcurrent!=songptr) {
  283.     if (parameter->mouse) { 
  284.       mouseptr=getmouseptr(songs,parameter,mousedata);
  285.       intheway=((mouseptr==songptr) || (mouseptr==songs->songcurrent)); 
  286.     }
  287.     else intheway=FALSE;
  288.     if (intheway)
  289.       mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  290.     unputcurrent(songs,parameter);
  291.     songs->songcurrent=songptr;
  292.     if (songs->song[songptr].picked!=0) 
  293.       putcurrent(songs,parameter,colorpicked|colorcurrent);
  294.     else
  295.       putcurrent(songs,parameter,coloritem|colorcurrent);
  296.     if (intheway)
  297.       mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  298.     movecursor(parameter);
  299.   }
  300.   else bellit();
  301. }
  302.  
  303. void printarrows(SONGSTYPE *songs, PARAMETERTYPE *parameter)
  304. /* displays PgUp and PgDn */
  305. /* moves away cursor */
  306. {
  307.   int column;
  308.  
  309.   if (songs->songcorner>1)
  310.     mycputs(parameter,parameter->maxcolumn-strlen(PGUP),1,PGUP,
  311.             coloroutline|colorborder);
  312.   else
  313.     for (column=1 ; column<=strlen(PGUP) ; column++)
  314.       mycputs(parameter,parameter->maxcolumn-column,1,"─",
  315.               coloroutline|colorborder);
  316.   if ((songs->songcorner+parameter->bigline-1)<parameter->hugeline)
  317.    mycputs(parameter,parameter->maxcolumn-strlen(PGDN),parameter->maxline,PGDN,
  318.            coloroutline|colorborder);
  319.   else
  320.     for (column=1 ; column<=strlen(PGUP) ; column++)
  321.       mycputs(parameter,parameter->maxcolumn-column,parameter->maxline,"─",
  322.               coloroutline|colorborder);
  323.   movecursor(parameter);
  324. }
  325.  
  326. void printsongs(SONGSTYPE *songs, PARAMETERTYPE *parameter, 
  327.                 MOUSETYPE *mousedata)
  328. /* displays all the menu items and PgUp-PgDn */
  329. /* moves away cursor */
  330. {
  331.   int bline,bcolumn; /* item coordinates */
  332.   int line,column; /* screen coordinates */
  333.   int songptr,songlimit;
  334.   int wrapper; /* used for clever column spacing */
  335.  
  336.   if (parameter->mouse)
  337.     mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  338.   wrapper=0;
  339.   column=3;
  340.   songlimit=parameter->hugeline;
  341.   for (bcolumn=1 ; bcolumn<=parameter->bigcolumn ; bcolumn++) {
  342.     songptr=songs->songcorner+(bcolumn-1)*parameter->hugeline;
  343.     cleverwrapper(parameter,&wrapper,&column);
  344.     for (line=3 , bline=1 ; bline<=parameter->bigline ; line++ , bline++)
  345.       if (songptr<=songlimit)
  346.         if (songptr==songs->songcurrent) 
  347.           if (songs->song[songptr].picked!=0)
  348.             putitem(column,line,&(songs->song[songptr++]),
  349.                     colorpicked|colorcurrent,parameter);
  350.           else
  351.             putitem(column,line,&(songs->song[songptr++]),
  352.                     coloritem|colorcurrent,parameter);
  353.         else 
  354.           if (songs->song[songptr].picked!=0)
  355.             putitem(column,line,&(songs->song[songptr++]),
  356.                     colorpicked|colorborder,parameter);
  357.           else
  358.             putitem(column,line,&(songs->song[songptr++]),
  359.                     coloritem|colorborder,parameter);
  360.       else
  361.         putitem(column,line,&(songs->song[0]),coloritem|colorborder,parameter);
  362.     column+=parameter->itemlength;
  363.     songlimit+=parameter->hugeline;
  364.     /* small check for the last menu item column sometime incomplete */
  365.     if (songlimit>songs->songnumber) songlimit=songs->songnumber;
  366.   }
  367.   if (parameter->mouse)
  368.     mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  369.   printarrows(songs,parameter);
  370. }
  371.  
  372. void dopgup(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  373. {
  374.   int bcolumn,bline; 
  375.  
  376.   if (songs->songcorner>1) {
  377.     /* move up half a screen */
  378.     songs->songcorner-=parameter->bigline/2;
  379.     /* make sure upper-left item exists */
  380.     if (songs->songcorner<1) songs->songcorner=1;
  381.     /* make sure current song is on the screen */
  382.     getbig(songs,parameter,&bcolumn,&bline);
  383.     if (bline>parameter->bigline) songs->songcurrent=songs->songcorner;
  384.     printsongs(songs,parameter,mousedata);
  385.   }
  386.   else 
  387.     /* can't scroll */
  388.     changecurrent(songs,parameter,mousedata,1);
  389. }
  390.  
  391. void dopgdn(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  392. {
  393.   int bcolumn,bline; 
  394.  
  395.   if ((songs->songcorner+parameter->bigline-1)<parameter->hugeline) {
  396.     /* move down half a screen */
  397.     songs->songcorner+=parameter->bigline/2;
  398.     /* no need to make sure upper-left item exists, it always does */
  399.     /* make sure current song is on the screen */
  400.     getbig(songs,parameter,&bcolumn,&bline);
  401.     if (bline<1) songs->songcurrent=songs->songcorner;
  402.     printsongs(songs,parameter,mousedata);
  403.   }
  404.   else 
  405.     /* can't scroll */
  406.     changecurrent(songs,parameter,mousedata,songs->songnumber);
  407. }
  408.  
  409. void doleft(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  410. {
  411.   int songptr;
  412.  
  413.   songptr=songs->songcurrent-parameter->hugeline;
  414.   if (songptr>=1) changecurrent(songs,parameter,mousedata,songptr);
  415.   else bellit();
  416. }
  417.  
  418. void doright(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  419. {
  420.   int songptr;
  421.  
  422.   songptr=songs->songcurrent+parameter->hugeline;
  423.   if (songptr<=songs->songnumber)
  424.     changecurrent(songs,parameter,mousedata,songptr);
  425.   else bellit();
  426. }
  427.  
  428. void doup(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  429. {
  430.   int wrapper; /* used for clever column spacing */
  431.   int bcolumn,bline;
  432.   int songlimit; /* first song of current column */
  433.   int songptr,column;
  434.  
  435.   getbig(songs,parameter,&bcolumn,&bline);
  436.   songlimit=parameter->hugeline*(bcolumn-1)+1;
  437.   if (bline==1) {
  438.     /* goes off screen */
  439.     if (songs->songcurrent==songlimit)
  440.       /* can't scroll vertically */
  441.       bellit();
  442.     else {
  443.       /* can scroll vertically */
  444.       if (parameter->mouse)
  445.         mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  446.       unputcurrent(songs,parameter);
  447.       myscrolldown(parameter);
  448.       songs->songcorner--;
  449.       songs->songcurrent--;
  450.       wrapper=0;
  451.       column=3;
  452.       songptr=songs->songcorner;
  453.       cleverwrapper(parameter,&wrapper,&column);
  454.       for (bcolumn=1 ; bcolumn<=parameter->bigcolumn ; bcolumn++) {
  455.         if (songptr==songs->songcurrent) 
  456.           if (songs->song[songptr].picked!=0) 
  457.             putitem(column,3,&(songs->song[songptr]),
  458.                     colorpicked|colorcurrent,parameter);
  459.           else
  460.             putitem(column,3,&(songs->song[songptr]),
  461.                     coloritem|colorcurrent,parameter);
  462.         else
  463.           if (songs->song[songptr].picked!=0)
  464.             putitem(column,3,&(songs->song[songptr]),
  465.                     colorpicked|colorborder,parameter);
  466.           else
  467.             putitem(column,3,&(songs->song[songptr]),
  468.                     coloritem|colorborder,parameter);
  469.         songptr+=parameter->hugeline;
  470.         if (songptr>songs->songnumber) break; /* unlikely though for up move */
  471.         column+=parameter->itemlength;
  472.         cleverwrapper(parameter,&wrapper,&column);
  473.       }
  474.       if (parameter->mouse)
  475.         mouseshow(mousedata->x,mousedata->y,&(mousedata->c),
  476.                   &(mousedata->color));
  477.       printarrows(songs,parameter);
  478.     }
  479.   }
  480.   else
  481.     /* stays on screen */
  482.     changecurrent(songs,parameter,mousedata,(songs->songcurrent-1));
  483. }
  484.  
  485. void dodown(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  486. {
  487.   int wrapper; /* used for clever column spacing */
  488.   int bline,bcolumn;
  489.   int songlimit; /* last song of current column */
  490.   int songptr,column;
  491.  
  492.   getbig(songs,parameter,&bcolumn,&bline);
  493.   songlimit=parameter->hugeline*bcolumn;
  494.   if (songlimit>songs->songnumber) songlimit=songs->songnumber;
  495.   if (bline==parameter->bigline) {
  496.     /* goes off screen */
  497.     if (songs->songcurrent==songlimit)
  498.       /* can't scroll vertically */
  499.       bellit();
  500.     else {
  501.       /* can scroll vertically */
  502.       if (parameter->mouse)
  503.         mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  504.       unputcurrent(songs,parameter);
  505.       myscrollup(parameter);
  506.       songs->songcorner++;
  507.       songs->songcurrent++;
  508.       wrapper=0;
  509.       column=3;
  510.       songptr=songs->songcorner+parameter->bigline-1;
  511.       cleverwrapper(parameter,&wrapper,&column);
  512.       for (bcolumn=1 ; bcolumn<=parameter->bigcolumn ; bcolumn++) {
  513.         if (songptr<=songs->songnumber)
  514.           if (songptr==songs->songcurrent) 
  515.             if (songs->song[songptr].picked!=0) 
  516.               putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  517.                       colorpicked|colorcurrent,parameter);
  518.             else
  519.               putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  520.                       coloritem|colorcurrent,parameter);
  521.           else
  522.             if (songs->song[songptr].picked!=0)
  523.               putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  524.                       colorpicked|colorborder,parameter);
  525.             else
  526.               putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  527.                       coloritem|colorborder,parameter);
  528.         songptr+=parameter->hugeline;
  529.         if (songptr>songs->songnumber) break; /* likely for down move */
  530.         column+=parameter->itemlength;
  531.         cleverwrapper(parameter,&wrapper,&column);
  532.       }
  533.       if (parameter->mouse)
  534.         mouseshow(mousedata->x,mousedata->y,&(mousedata->c),
  535.                   &(mousedata->color));
  536.       printarrows(songs,parameter);
  537.     }
  538.   }
  539.   else 
  540.     /* stays on screen */
  541.     if (songs->songcurrent<songlimit) 
  542.       changecurrent(songs,parameter,mousedata,(songs->songcurrent+1));
  543.     else bellit();
  544. }
  545.  
  546. void dohome(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  547. {
  548.   int bcolumn,bline; 
  549.  
  550.   if (songs->songcorner!=1) {
  551.     songs->songcorner=1;
  552.     /* make sure current song is on the screen */
  553.     getbig(songs,parameter,&bcolumn,&bline);
  554.     if (bline>parameter->bigline) songs->songcurrent=1;
  555.     printsongs(songs,parameter,mousedata);
  556.   }
  557.   else
  558.     /* can't scroll */
  559.     changecurrent(songs,parameter,mousedata,1);
  560. }
  561.  
  562. void doend(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  563. {
  564.   int bcolumn,bline; 
  565.  
  566.   if (songs->songcorner!=(parameter->hugeline-parameter->bigline+1)) {
  567.     songs->songcorner=parameter->hugeline-parameter->bigline+1;
  568.     /* make sure current song is on the screen */
  569.     getbig(songs,parameter,&bcolumn,&bline);
  570.     if (bline<1) songs->songcurrent=songs->songnumber;
  571.     printsongs(songs,parameter,mousedata);
  572.   }
  573.   else
  574.     /* can't scroll */
  575.     changecurrent(songs,parameter,mousedata,songs->songnumber);
  576. }
  577.  
  578. void doatslash(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  579. {
  580.   int songptr;
  581.  
  582.   songs->songpriority=0;
  583.   /* use current menu item as a basis for reversing statuses */
  584.   if (songs->song[songs->songcurrent].picked!=0)
  585.     for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
  586.       songs->song[songptr].picked=0;
  587.   else
  588.     for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
  589.       songs->song[songptr].picked=++songs->songpriority;
  590.   printsongs(songs,parameter,mousedata);
  591. }
  592.  
  593. void dostar(SONGSTYPE *songs) 
  594.   int songptr,songlimit,songnext,songsearch;
  595.  
  596.   if (songs->songpriority==0) bellit();
  597.   else {
  598.     songs->songpriority=0;
  599.     for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
  600.       if (songs->song[songptr].picked!=0) {
  601.         songs->songpriority++;
  602.         songs->song[songptr].picked=-1;
  603.       }
  604.     for (songlimit=songs->songpriority ; songlimit>=1 ; songlimit--) {
  605.       songnext=1+(rand() % songlimit);
  606.       songsearch=0;
  607.       for (songptr=1 ; songptr<=songnext ; songptr++) {
  608.         songsearch++;
  609.         while (songs->song[songsearch].picked>=0) songsearch++;
  610.       }
  611.       songs->song[songsearch].picked=songlimit;
  612.     }
  613.   }
  614. }
  615.  
  616. void dospgup(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  617. {
  618.   int songptr;
  619.  
  620.   songptr=songs->songcorner+(parameter->bigcolumn-1)*parameter->hugeline;
  621.   changecurrent(songs,parameter,mousedata,songptr);
  622. }
  623.  
  624. void dospgdn(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  625. {
  626.   int songptr;
  627.  
  628.   songptr=songs->songcorner+(parameter->bigcolumn-1)*parameter->hugeline+
  629.           parameter->bigline-1;
  630.   if (songptr>songs->songnumber) songptr=songs->songnumber;
  631.   changecurrent(songs,parameter,mousedata,songptr);
  632. }
  633.  
  634. void dosleft(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  635. {
  636.   int songptr;
  637.   int bline,bcolumn;
  638.  
  639.   getbig(songs,parameter,&bcolumn,&bline);
  640.   songptr=songs->songcorner+bline-1;
  641.   changecurrent(songs,parameter,mousedata,songptr);
  642. }
  643.  
  644. void dosright(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  645. {
  646.   int songptr;
  647.   int bline,bcolumn;
  648.  
  649.   getbig(songs,parameter,&bcolumn,&bline);
  650.   songptr=songs->songcorner+(parameter->bigcolumn-1)*parameter->hugeline+
  651.           bline-1;
  652.   if (songptr>songs->songnumber) songptr-=parameter->hugeline;
  653.   changecurrent(songs,parameter,mousedata,songptr);
  654. }
  655.  
  656. void dosup(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  657. {
  658.   int songptr;
  659.   int bline,bcolumn;
  660.  
  661.   getbig(songs,parameter,&bcolumn,&bline);
  662.   songptr=songs->songcorner+(bcolumn-1)*parameter->hugeline;
  663.   changecurrent(songs,parameter,mousedata,songptr);
  664. }
  665.  
  666. void dosdown(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  667. {
  668.   int songptr;
  669.   int bline,bcolumn;
  670.  
  671.   getbig(songs,parameter,&bcolumn,&bline);
  672.   songptr=songs->songcorner+(bcolumn-1)*parameter->hugeline+
  673.           parameter->bigline-1;
  674.   if (songptr>(parameter->hugeline*bcolumn)) 
  675.     songptr=parameter->hugeline*bcolumn;
  676.   if (songptr>songs->songnumber) songptr=songs->songnumber;
  677.   changecurrent(songs,parameter,mousedata,songptr);
  678. }
  679.  
  680. void doshome(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  681. {
  682.   changecurrent(songs,parameter,mousedata,songs->songcorner);
  683. }
  684.  
  685. void dosend(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  686. {
  687.   int songptr;
  688.  
  689.   songptr=songs->songcorner+parameter->bigline-1;
  690.   if (songptr>parameter->hugeline) songptr=parameter->hugeline;
  691.   changecurrent(songs,parameter,mousedata,songptr);
  692. }
  693.  
  694. void doscenter(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  695. {
  696.   int songptr,songlimit;
  697.   int bcolumn;
  698.  
  699.   bcolumn=(parameter->bigcolumn+1)/2;
  700.   songptr=songs->songcorner+parameter->hugeline*(bcolumn-1);
  701.   songlimit=songptr+parameter->bigline-1;
  702.   if (songlimit>(parameter->hugeline*bcolumn)) 
  703.     songlimit=parameter->hugeline*bcolumn;
  704.   songptr=(songptr+songlimit)/2;
  705.   changecurrent(songs,parameter,mousedata,songptr);
  706. }
  707.  
  708. void dospace(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  709. {
  710.   int intheway,mouseptr;
  711.  
  712.   if (parameter->mouse) { 
  713.     mouseptr=getmouseptr(songs,parameter,mousedata);
  714.     intheway=(mouseptr==songs->songcurrent);
  715.   }
  716.   else intheway=FALSE;
  717.   if (intheway)
  718.     mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  719.   if (songs->song[songs->songcurrent].picked!=0) {
  720.     songs->song[songs->songcurrent].picked=0;
  721.     putcurrent(songs,parameter,coloritem|colorcurrent);
  722.   }
  723.   else {
  724.     songs->song[songs->songcurrent].picked=++songs->songpriority;
  725.     putcurrent(songs,parameter,colorpicked|colorcurrent);
  726.   }
  727.   if (intheway)
  728.     mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  729.   movecursor(parameter);
  730. }
  731.  
  732. void domspace(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  733. {
  734.   int mouseptr,tempcurrent;
  735.  
  736.   mouseptr=getmouseptr(songs,parameter,mousedata);
  737.   mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  738.   if (songs->song[mouseptr].picked!=0) 
  739.     songs->song[mouseptr].picked=0;
  740.   else 
  741.     songs->song[mouseptr].picked=++songs->songpriority;
  742.   if (mouseptr==songs->songcurrent)
  743.     if (songs->song[mouseptr].picked!=0) 
  744.       putcurrent(songs,parameter,colorpicked|colorcurrent);
  745.     else 
  746.       putcurrent(songs,parameter,coloritem|colorcurrent);
  747.   else {
  748.     tempcurrent=songs->songcurrent;
  749.     songs->songcurrent=mouseptr;
  750.     if (songs->song[mouseptr].picked!=0) 
  751.       putcurrent(songs,parameter,colorpicked|colorborder);
  752.     else 
  753.       putcurrent(songs,parameter,coloritem|colorborder);
  754.     songs->songcurrent=tempcurrent;
  755.   }
  756.   mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  757.   movecursor(parameter);
  758. }
  759.  
  760. void domup(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  761. {
  762.   int wrapper; /* used for clever column spacing */
  763.   int bcolumn,bline;
  764.   int songptr,column;
  765.   struct time timep;
  766.   int time,oldtime;
  767.  
  768.   if (songs->songcorner!=1) {
  769.     gettime(&timep);
  770.     oldtime=((int)timep.ti_hund)+100*((int)timep.ti_sec);
  771.     mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  772.     getbig(songs,parameter,&bcolumn,&bline);
  773.     if (bline==parameter->bigline) {
  774.       unputcurrent(songs,parameter);
  775.       songs->songcurrent--;
  776.     }
  777.     songs->songcorner--;
  778.     myscrolldown(parameter);
  779.     if (bline==parameter->bigline)
  780.       if (songs->song[songs->songcurrent].picked!=0)
  781.         putcurrent(songs,parameter,colorpicked|colorcurrent);
  782.       else
  783.         putcurrent(songs,parameter,coloritem|colorcurrent);
  784.     wrapper=0;
  785.     column=3;
  786.     songptr=songs->songcorner;
  787.     cleverwrapper(parameter,&wrapper,&column);
  788.     for (bcolumn=1 ; bcolumn<=parameter->bigcolumn ; bcolumn++) {
  789.       if (songptr==songs->songcurrent) 
  790.         if (songs->song[songptr].picked!=0) 
  791.           putitem(column,3,&(songs->song[songptr]),
  792.                   colorpicked|colorcurrent,parameter);
  793.         else
  794.           putitem(column,3,&(songs->song[songptr]),
  795.                   coloritem|colorcurrent,parameter);
  796.       else
  797.         if (songs->song[songptr].picked!=0)
  798.           putitem(column,3,&(songs->song[songptr]),
  799.                   colorpicked|colorborder,parameter);
  800.         else
  801.           putitem(column,3,&(songs->song[songptr]),
  802.                   coloritem|colorborder,parameter);
  803.       songptr+=parameter->hugeline;
  804.       if (songptr>songs->songnumber) break; /* unlikely though for up move */
  805.       column+=parameter->itemlength;
  806.       cleverwrapper(parameter,&wrapper,&column);
  807.     }
  808.     mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  809.     printarrows(songs,parameter);
  810.     do {
  811.       gettime(&timep);
  812.       time=((int)timep.ti_hund)+100*((int)timep.ti_sec)-oldtime;
  813.       if (time<0) time+=6000;
  814.     } while (time<SCROLLDELAY);
  815.   }
  816. }
  817.  
  818. void domdown(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  819. {
  820.   int wrapper; /* used for clever column spacing */
  821.   int bline,bcolumn;
  822.   int songptr,column;
  823.   struct time timep;
  824.   int time,oldtime;
  825.  
  826.   if ((songs->songcorner+parameter->bigline-1)<parameter->hugeline) {
  827.     gettime(&timep);
  828.     oldtime=((int)timep.ti_hund)+100*((int)timep.ti_sec);
  829.     mousehide(mousedata->x,mousedata->y,mousedata->c,mousedata->color);
  830.     getbig(songs,parameter,&bcolumn,&bline);
  831.     if (bline==1) {
  832.       unputcurrent(songs,parameter);
  833.       songs->songcurrent++;
  834.     }
  835.     songs->songcorner++;
  836.     myscrollup(parameter);
  837.     if (bline==1) 
  838.       if (songs->song[songs->songcurrent].picked!=0)
  839.         putcurrent(songs,parameter,colorpicked|colorcurrent);
  840.       else
  841.         putcurrent(songs,parameter,coloritem|colorcurrent);
  842.     wrapper=0;
  843.     column=3;
  844.     songptr=songs->songcorner+parameter->bigline-1;
  845.     cleverwrapper(parameter,&wrapper,&column);
  846.     for (bcolumn=1 ; bcolumn<=parameter->bigcolumn ; bcolumn++) {
  847.       if (songptr<=songs->songnumber)
  848.         if (songptr==songs->songcurrent) 
  849.           if (songs->song[songptr].picked!=0) 
  850.             putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  851.                     colorpicked|colorcurrent,parameter);
  852.           else
  853.             putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  854.                     coloritem|colorcurrent,parameter);
  855.         else
  856.           if (songs->song[songptr].picked!=0)
  857.             putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  858.                     colorpicked|colorborder,parameter);
  859.           else
  860.             putitem(column,parameter->maxline-2,&(songs->song[songptr]),
  861.                     coloritem|colorborder,parameter);
  862.       songptr+=parameter->hugeline;
  863.       if (songptr>songs->songnumber) break; /* likely for down move */
  864.       column+=parameter->itemlength;
  865.       cleverwrapper(parameter,&wrapper,&column);
  866.     }
  867.     mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
  868.     printarrows(songs,parameter);
  869.     do {
  870.       gettime(&timep);
  871.       time=((int)timep.ti_hund)+100*((int)timep.ti_sec)-oldtime;
  872.       if (time<0) time+=6000;
  873.     } while (time<SCROLLDELAY);
  874.   }
  875. }
  876.  
  877. int picksongs(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
  878. /* updates the menu */
  879. {
  880.  
  881.   songs->songpriority=0;
  882.   do {
  883.     if (bioskey(1))
  884.       switch (bioskey(0)) {
  885.         case KEYESC:return(TRUE);
  886.         case KEYENTER:return(FALSE);
  887.         case KEYSPACE:dospace(songs,parameter,mousedata);
  888.                       break;
  889.         case KEYPGUP:dopgup(songs,parameter,mousedata);
  890.                      break;
  891.         case KEYPGDN:dopgdn(songs,parameter,mousedata);
  892.                      break;
  893.         case KEYLEFT:doleft(songs,parameter,mousedata);
  894.                      break;
  895.         case KEYRIGHT:doright(songs,parameter,mousedata);
  896.                       break;
  897.         case KEYUP:doup(songs,parameter,mousedata);
  898.                    break;
  899.         case KEYDOWN:dodown(songs,parameter,mousedata);
  900.                      break;
  901.         case KEYHOME:dohome(songs,parameter,mousedata);
  902.                      break;
  903.         case KEYEND:doend(songs,parameter,mousedata);
  904.                     break;
  905.         case KEYATSLASH:doatslash(songs,parameter,mousedata);
  906.                         break;
  907.         case KEYSTAR1:dostar(songs);
  908.                       break;
  909.         case KEYSTAR2:dostar(songs);
  910.                       break;
  911.         case SKEYPGUP:dospgup(songs,parameter,mousedata);
  912.                       break;
  913.         case SKEYPGDN:dospgdn(songs,parameter,mousedata);
  914.                       break;
  915.         case SKEYLEFT:dosleft(songs,parameter,mousedata);
  916.                       break;
  917.         case SKEYRIGHT:dosright(songs,parameter,mousedata);
  918.                        break;
  919.         case SKEYUP:dosup(songs,parameter,mousedata);
  920.                     break;
  921.         case SKEYDOWN:dosdown(songs,parameter,mousedata);
  922.                       break;
  923.         case SKEYHOME:doshome(songs,parameter,mousedata);
  924.                       break;
  925.         case SKEYEND:dosend(songs,parameter,mousedata);
  926.                      break;
  927.         case SKEYCENTER:doscenter(songs,parameter,mousedata);
  928.                         break;
  929.         default:bellit();
  930.                 break;
  931.       } 
  932.     else
  933.       if (parameter->mouse)
  934.         switch (readmouse(songs,parameter,mousedata)) {
  935.           case KEYESC:return(TRUE);
  936.           case KEYENTER:return(FALSE);
  937.           case KEYSPACE:domspace(songs,parameter,mousedata);
  938.                         break;
  939.           case KEYUP:domup(songs,parameter,mousedata);
  940.                      break;
  941.           case KEYDOWN:domdown(songs,parameter,mousedata);
  942.                        break;
  943.           default:break;
  944.         }
  945.   } while (TRUE);
  946. }
  947.