//
// this file by brian martin 1996
// brian@phyast.pitt.edu
//
// this is part of the source for the MedDLe quake model viewer/editor
//
//// mouse
#include<go32.h>
#include<dpmi.h>
#include<stdlib.h>
#include<stdio.h>
#include"bg_mouse.h"
#include"bg_grx.h"

#ifndef USEGRX
#include <grx20.h>
GrContext *MouseContext;
GrContext *CrossHairCur;
GrContext *PointingCur;
GrContext *BackgroundContext;
GrContext *TempContext;
#endif

int bg_x,bg_y;
#define MOUSE 0x33

__dpmi_regs r;

int BG_MouseLeft,
    BG_MouseRight,
    BG_MouseMiddle;
int BG_MouseX,
    BG_MouseY;

int HotX, HotY;
int Speed;

void BG_InitMouse()
{
    // init mouse
    r.x.ax = 0;
    __dpmi_int(MOUSE,&r);
    // hide
    r.x.ax = 2;
    __dpmi_int(MOUSE, &r);
    BG_MouseRange(0,0,BG_ScreenWidth-1,BG_ScreenHeight-1);
    // speed
    BG_MouseSpeed(4);
    BG_MouseToXY(BG_ScreenWidth>>1,BG_ScreenHeight>>1);
    BG_MouseStatus();

#ifndef USEGRX

    MouseContext = GrCreateContext(16,16,NULL,NULL);
    BackgroundContext = GrCreateContext(16,16,NULL,NULL);


    CrossHairCur= GrCreateContext(16,16,NULL,NULL);
    GrSetContext(CrossHairCur);
    GrFilledBox(0,0,15,15,0);
    GrBox(4,4,10,10,15);
    GrFilledBox(4,6,10,8,0);
    GrFilledBox(6,4,8,10,0);

    PointingCur=GrCreateContext(16,16,NULL,NULL);
    GrSetContext(PointingCur);
    GrFilledBox(0,0,15,15,0);
    GrLine(0,0,10,10,15);
    GrLine(0,0,0,14,15);
    GrLine(0,14,4,10,15);
    GrLine(4,10,10,10,15);
//  GrLine(4,10,6,14,15);

   //   BG_MousePointing();
    BG_MouseCrossHairs();
    GrSetContext(NULL);
    GrImageModeColor(0);
    bg_x=BG_MouseX;
    bg_y=BG_MouseY;

#endif

}

void BG_MousePointing(void)
{
    HotX=0;  HotY=0;

    GrBitBlt(MouseContext,
            0,0,
            PointingCur,
            0,
            0,
            16,
            16,
            GrWRITE
            );

}
void BG_MouseCrossHairs(void)
{
    HotX=7;HotY=7;

    GrBitBlt(MouseContext,
            0,0,
            CrossHairCur,
            0,
            0,
            16,
            16,
            GrWRITE
            );

}

void BG_MouseStatus()
{
    r.x.ax = 3;
    __dpmi_int(MOUSE,&r);
    BG_MouseX = (r.x.cx>>3);
    BG_MouseY = r.x.dx>>3;
    BG_MouseLeft = ((r.x.bx & 0x01) != 0);
    BG_MouseRight = ((r.x.bx & 0x02) != 0);
    BG_MouseMiddle =   ((r.x.bx & 0x04) != 0);
}
void BG_MouseSpeed(int s)
{
    // speed
    r.x.ax = 0x0f;
    r.x.cx = s;
    r.x.dx = s;
    __dpmi_int(MOUSE, &r);

}
void BG_MouseRange(int x1, int y1, int x2, int y2)
{
    r.x.ax = 7;
    r.x.cx = (x1<<3);
    r.x.dx = (x2<<3);
    __dpmi_int(MOUSE,&r);
    r.x.ax = 8;
    r.x.cx = (y1<<3);
    r.x.dx = (y2<<3);
    __dpmi_int(MOUSE,&r);
}
void BG_MouseToXY(int xpos, int ypos)
{
   r.x.ax = 4;
   r.x.cx = 8*(BG_MouseX = xpos);
   r.x.dx = 8*(BG_MouseY = ypos);
   __dpmi_int(MOUSE,&r);
}

void BG_MouseShow(void)
{
#ifndef USEGRX

//  TempContext=GrCurrentContext();

//  GrSetContext(MouseContext);
    GrBitBlt(BackgroundContext,
            0,0,
            NULL,
            BG_MouseX-HotX,
            BG_MouseY-HotY,
            BG_MouseX+16-HotX,
            BG_MouseY+16-HotY,
            GrWRITE
            );
    bg_x=BG_MouseX;
    bg_y=BG_MouseY;

    GrBitBlt(NULL,
            BG_MouseX-HotX,BG_MouseY-HotY,
            MouseContext,
            0,
            0,
            16,
            16,
            GrIMAGE
            );
//  BG_PutPixel(BG_MouseX,BG_MouseY,15);
//  GrSetContext(TempContext);

#endif


}

void BG_MouseHide(void)
{
#ifndef USEGRX

//  TempContext=GrCurrentContext();

//  GrSetContext(MouseContext);
    GrBitBlt(NULL,
            bg_x-HotX,bg_y-HotY,
            BackgroundContext,
            0,
            0,
            16,
            16,
            GrWRITE
            );
/*
    GrBitBlt(NULL,
            BG_MouseX,BG_MouseY,
            MouseContext,
            0,
            0,
            16,
            16,
            GrIMAGE
            );
//  BG_PutPixel(BG_MouseX,BG_MouseY,15);
    GrSetContext(TempContext);
 */
#endif


}

/*
#define INVSCRNMASK 0xFFFF
#define INVCURSMASK 0x7700
#define MOUSE 51
#define ESC 0x1b            /* Define the escape key    */
// mouse vars
//union              REGS regs;
//struct SREGS           sregs;
/*
int                              MouseOK = 0;
int                              NoButtons = 2;
int                              MidPressed,RightPressed,LeftPressed;
MouseDef                         Mymouse;
int                              MouseX = 0, MouseY = 0;

// bg mouse cur
static BYTE * pMouseCursor;
/* default 12x16 cursor (planar format) */
/*static BYTE default_mouse_cursor[] = { 3, 0, 16, 0,
     15,  0,  0, 15,  0,  0, 15,  0,  0, 15,  0,  0,
     15, 15,  0, 15, 15,  0, 15, 15,  0, 15,  0,  0,
     15,  0,  0,  0, 15,  0,  0, 15,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0, 15,  0,  0, 15,  0,  0, 15,  0,  0,
     15,  0,  0, 15, 15,  0, 15, 15,  0, 15,  0,  0,
      0,  0,  0,  0, 15,  0,  0, 15,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0, 15,  0,  0, 15,  0,  0,
     15,  0,  0, 15,  0,  0, 15, 15,  0, 15,  0,  0,
     15,  0,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0,  0,
     15,  0,  0, 15,  0,  0, 15,  0,  0, 15,  0,  0,
     15,  0,  0, 15,  0,  0, 15,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
};



void InitMouse()
{
   regs.x.ax = 0;
   int86(MOUSE,&regs,&regs);
   MouseOK = regs.x.ax;
   NoButtons = regs.x.bx;
}

void ShowMouse()
{
   regs.x.ax = 1;
   int86(MOUSE,&regs,&regs);
}

void HideMouse()
{
   regs.x.ax = 2;
   int86(MOUSE,&regs,&regs);
}

void MouseXY()
{
   regs.x.ax = 3;
   int86(MOUSE,&regs,&regs);
   MouseX = regs.x.cx/2;
   MouseY = regs.x.dx;
   LeftPressed =  ((regs.x.bx & 0x01) != 0);
   RightPressed = ((regs.x.bx & 0x02) != 0);
   MidPressed =   ((regs.x.bx & 0x04) != 0);
}

void MouseToXY(int xpos, int ypos)
{
   regs.x.ax = 4;
   regs.x.cx = 2*(MouseX = xpos);
   regs.x.dx = (MouseY = ypos);
   int86(MOUSE,&regs,&regs);
}

int MousePressCount(ButtonType button, int *status)
{
   regs.x.ax = 5;
   regs.x.bx = button;
   int86(MOUSE,&regs,&regs);
   MouseX = regs.x.cx/2;
   MouseY = regs.x.dx;
   *status = regs.x.ax;
   return regs.x.bx;
}

int MouseReleaseCount(ButtonType button, int *status)
{
   regs.x.ax = 6;
   regs.x.bx = button;
   int86(MOUSE,&regs,&regs);
   MouseX = regs.x.cx/2;
   MouseY = regs.x.dx;
   *status = regs.x.ax;
   return regs.x.bx;
}

void MouseXRange(int x1, int x2)
{
   regs.x.ax = 7;
   regs.x.cx = x1*2;
   regs.x.dx = x2*2;
   int86(MOUSE,&regs,&regs);
}

void MouseYRange(int y1, int y2)
{
   regs.x.ax = 8;
   regs.x.cx = y1;
   regs.x.dx = y2;
   int86(MOUSE,&regs,&regs);
}
/*
void DefineGraphMouse(MouseDef mouse, int xhot, int yhot)
{
   regs.x.ax = 9;
   regs.x.bx = xhot;
   regs.x.cx = yhot;
   regs.x.dx = FP_OFF(&mouse);
   sregs.es = FP_SEG(&mouse);
   int86x(MOUSE,&regs,&regs,&sregs);
}
*/
/*
void DefineTextMouse(MouseMode mode, int scrnmask, int cursormask)
{
   regs.x.ax = 10;
   regs.x.bx = mode;
   regs.x.cx = scrnmask;
   regs.x.cx = cursormask;
   int86(MOUSE,&regs,&regs);
}

void ReadMouseMickey(int *Xspeed, int *Yspeed)
{
   regs.x.ax = 11;
   int86(MOUSE,&regs,&regs);
   *Xspeed = regs.x.cx;
   *Yspeed = regs.x.dx;
/*
   if Xspeed > 0 then moving in positive x direction
   if Yspeed > 0 then moving in positive y direction
*//*
}

void SetMouseMickey(int Xspeed, int Yspeed)
{
   regs.x.ax = 15;
   regs.x.cx = (unsigned) Xspeed;
   regs.x.dx = (unsigned) Yspeed;
   int86(MOUSE,&regs,&regs);
}

void TextCursorOff()
{
   regs.x.cx = 0x2000;
   regs.x.ax = 0x0100;
   int86(0x10,&regs,&regs);
}

void TextCursorOn()
{
   regs.x.cx = 0x0C0D;
   regs.x.ax = 0x0100;
   int86(0x10,&regs,&regs);
}
 */
