/* Warning! This C source contains extended characters! */

#include <dos.h>
#include <bios.h>
#include <musique.h>
#include <mouse.e>

int colorcursor;

void mouseshow(int x, int y, char *c, int *color)
/* Turbo-C doesn't like extended or non-text modes */
/* Turbo-C scrolls the screen too much (lower-right corner) */
/* prints the mouse cursor */
{
  union REGS regs;

  regs.h.ah=(unsigned)'\x2'; /* set cursor position */
  regs.h.bh=(unsigned)'\x0';
  regs.h.dl=(unsigned char)(x-1);
  regs.h.dh=(unsigned char)(y-1);
  int86(0x10,&regs,&regs);
  regs.h.ah=(unsigned)'\x8'; /* read one character */
  regs.h.bh=(unsigned)'\x0';
  int86(0x10,&regs,&regs);
  *c=(char)regs.h.al;
  *color=(int)regs.h.ah;
  regs.h.ah=(unsigned)'\x9'; /* print one character */
  regs.h.bh=(unsigned)'\x0';
  regs.x.cx=(unsigned)0x1;
  regs.h.bl=(unsigned char)((*color&0xF)|colorcursor);
  regs.h.al=(unsigned)*c;
  int86(0x10,&regs,&regs);
}

void mousehide(int x, int y, char c, int color)
/* Turbo-C doesn't like extended or non-text modes */
/* Turbo-C scrolls the screen too much (lower-right corner) */
/* hides the mouse cursor */
{
  union REGS regs;

  regs.h.ah=(unsigned)'\x2'; /* set cursor position */
  regs.h.bh=(unsigned)'\x0';
  regs.h.dl=(unsigned char)(x-1);
  regs.h.dh=(unsigned char)(y-1);
  int86(0x10,&regs,&regs);
  regs.h.ah=(unsigned)'\x9'; /* print one character */
  regs.h.bh=(unsigned)'\x0';
  regs.x.cx=(unsigned)0x1;
  regs.h.bl=(unsigned char)color;
  regs.h.al=(unsigned)c;
  int86(0x10,&regs,&regs);
}

int mouseinit(void)
/* returns TRUE iff mouse responding */
{
  union REGS regs;

  regs.x.ax=(unsigned)0x0;
  int86(0x33,&regs,&regs);
  return((int)regs.x.ax);
}

void mouseratio(int X, int Y)
/* sets X/Y motion/pixel ratio */
{
  union REGS regs;

  regs.x.ax=(unsigned)0xF;
  regs.x.cx=(unsigned)X;
  regs.x.dx=(unsigned)Y;
  int86(0x33,&regs,&regs);
}

void mouselimits(int xmin, int ymin, int xmax, int ymax)
/* sets X/Y intervals */
{
  union REGS regs;

  regs.x.ax=(unsigned)0x7;
  regs.x.cx=(unsigned)(xmin<<4);
  regs.x.dx=(unsigned)(xmax<<4);
  int86(0x33,&regs,&regs);
  regs.x.ax=(unsigned)0x8;
  regs.x.cx=(unsigned)(ymin<<4);
  regs.x.dx=(unsigned)(ymax<<4);
  int86(0x33,&regs,&regs);
}

void mousewrite(int X, int Y)
/* sets mouse position */
{
  union REGS regs;

  regs.x.ax=(unsigned)0x4;
  regs.x.cx=(unsigned)(X<<4);
  regs.x.dx=(unsigned)(Y<<4);
  int86(0x33,&regs,&regs);
}

void mouseread(MOUSETYPE *mousedata)
/* reads mouse position and button status*/
{
  union REGS regs;

  regs.x.ax=(unsigned)0x3;
  int86(0x33,&regs,&regs);
  mousedata->x=((int)regs.x.cx)>>4;
  mousedata->y=((int)regs.x.dx)>>4;
  mousedata->left=((int)regs.x.bx & 0x1);
  mousedata->right=((int)regs.x.bx & 0x2);
}

int setupmouse(PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
/* returns TRUE iff could set up the mouse */
{
  if (mouseinit()) {
    mousedata->x=parameter->maxcolumn/2;
    mousedata->y=parameter->maxline/2;
    mouseratio(XRATIO,YRATIO);
    mouselimits(2,2,parameter->maxcolumn-1,parameter->maxline-1);
    mousewrite(mousedata->x,mousedata->y);
    return(TRUE);
  }
  else return (FALSE);
}

int readmouse(SONGSTYPE *songs, PARAMETERTYPE *parameter, MOUSETYPE *mousedata)
/* translates mouse activity in equivalent keyboard keys */
/* left button is <Space> */
/* right button is <Enter> */
/* both buttons are <Escape> since hard to do by mistake */
{
  int left,right,x,y;

  left=mousedata->left;
  right=mousedata->right;
  x=mousedata->x;
  y=mousedata->y;
  mouseread(mousedata);
  if ((mousedata->x!=x) || (mousedata->y!=y)) {
    mousehide(x,y,mousedata->c,mousedata->color);
    mouseshow(mousedata->x,mousedata->y,&(mousedata->c),&(mousedata->color));
    movecursor(parameter);
  }
  if (mousedata->left)
    if (mousedata->right) {
      if (!left && !right) return(KEYESC);
    }
    else {
      if (!left) return(KEYSPACE);
    }
  else
    if (mousedata->right)
      if (!right) return(KEYENTER);
  if (mousedata->y==2)
    if (songs->songcorner>1) return(KEYUP);
  if (mousedata->y==(parameter->maxline-1))
    if ((songs->songcorner+parameter->bigline)<=parameter->hugeline) 
      return(KEYDOWN);
  return(FALSE);
}
