// Copyright(c) SuperSpirit Studio,Superspirit
#ifndef XRH_MOUSE_LIARBRY
#define XRH_MOUSE_LIARBRY
#include <DOS.H>
#include <STDIO.H>
#include <CONIO.H>
#include <STDLIB.H>
#define MOUSE_INTERRUPT 0x33
#define MOUSE_MAX_EVENT 3
#define Is_Here(x,y,x0,y0) (-Here_Range<=(((x)-(x0))>0?((x)-(x0)):((x0)-(x)))&&Here_Range>=(((x)-(x0))>0?((x)-(x0)):((x0)-(x)))&&-Here_Range<=(((y)-(y0))>0?((y)-(y0)):((y0)-(y)))&&Here_Range>=(((y)-(y0))>0?((y)-(y0)):((y0)-(y))))
int far Here_Range=2; // Mouse Click Range
int far Mouse_Locked=0; // Mouse Locked Switch 0-> Unlocked ,1->Locked
int far DBclick_Delay=6;// Mouse Double Clicked Time 1==> 1/18.2(s)
struct Mouse_Status{
int Mouse_x;
int Mouse_y;
int Mouse_Button_Status; // 现时鼠标按键状态
// bit0-左键
// bit1-右键
// bit2-中键
// 0-释放状态 1-按下状态
}Mouse_Now_Status;
struct Mouse_Event{
int Mouse_x;
int Mouse_y;
int Which_Button; // 1 Left Button,2 Right Button,4 Middle
int Event_ID;
// Event_ID =0 Nothing Happend!
// Event_ID =1 Mouse Moving.
// Event_ID =2 Click Event Happend.
// Event_ID =3 Mouse Button Down.
// Event_ID =4 Mouse Button Up.
// Event_ID =5 Double Click Event Happend.
unsigned Button_Status;
};
// Mouse_Event far Event[MOUSE_MAX_EVENT]={0,0,0};// Event Stack To Restore 3 Event Maxium.
Mouse_Event far Event={0,0,0,0,0};
// int far Full=0,Empty=1;// Full=1,Event Full;Empty=1,Event Empty.
// int far Event_Start=0,Event_End=0;
// int far Mouse_Button_Num=0;
unsigned long far Click_Time[3]={0,0,0};
unsigned long far *Time_p_=((unsigned long far *)0x0000046cl);
// Can Not Load *Time_p_ Correctly And Get Right Data ,I Don't Know Why?
int far OldEvent=0;
int far User_App_Running=0;
unsigned far Old_Event_Mask=0;
int far Old_M_x=-1,far Old_M_y=-2;
int far DB_Old_x=-1,far DB_Old_y=-2;
// int far Mouse=0;
const unsigned far _Mouse_Move_ =0x01,far _L_Button_Down_=0x02,far _L_Button_Up_=0x04;
const unsigned far _R_Button_Down_=0x08,far _R_Button_Up_ =0x10, far _M_Button_Down_=0x20;
const unsigned far _M_Button_Up_=0x40;
const unsigned far _Mouse_Nothing_=0,/*far _Mouse_Move_=1, */far _Mouse_Button_Click_=2,far _Mouse_Button_Down_=3,far _Mouse_Button_Up_=4,far _Mouse_Button_DBclick_=5;
const unsigned far _L_Button_=1,far _R_Button_=2,far _M_Button_=4;
void far User_App();
// int far Is_Here(int x,int y,int x0,int y0);
int far Hand_Shape[2][16] =
{
0xf3ff,0xe1ff,0xe1ff,0xe1ff,
0xe001,0xe000,0xe000,0xe000,
0x8000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x8001,0xc003,
0x0000,0x0c00,0x0c00,0x0c00,
0x0c00,0x0db6,0x0db6,0x0db6,
0x0db6,0x6ffe,0x6ffe,0x6ffe,
0x7ffe,0x7ffe,0x3ffc,0x0000
};
int far Arrow_Shape[2][16] =
{
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0x0000,0x4000,0x6000,0x7000,
0x7800,0x7c00,0x7e00,0x7f00,
0x7f80,0x7e00,0x7c00,0x4600,
0x0600,0x0300,0x0300,0x0180
};
int far Aim_Shape[2][16] =
{
{0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff},
{0x0100,0x0fe0,0x0100,0x0100,
0x4104,0x4104,0x4104,0xfffe,
0x4104,0x4104,0x4104,0x0100,
0x0100,0x0fe0,0x0100,0x0000,
}
};
class MyMouse
{
public:
static int MyMouse_Object_Num;
private:
REGPACK regs;
static int Mouse; // 1= Mouse Driver Exist,0=Mouse Driver Not Exist,Error.
static int Mouse_Button_Num; // Number Of Your Mouse Button.
void Mouse_Setup_User_Application(void far User_App(),unsigned Event_Mask);
// 挂接用户鼠标中断处理程序
// 输入参数: AX=0ch
// CX=事件屏蔽(event_mask)
// bit0-鼠标移动
// bit1-鼠标左键按下
// bit2-鼠标左键释放
// bit3-鼠标右键按下
// bit4-鼠标右键释放
// bit5-鼠标中键按下 (Mouse Systems/Logitech mouse)
// bit6-鼠标中键释放 (Mouse Systems/Logitech mouse)
// 各位置1 - 发生相应动作时调用用户程序
// DX=指向中断子程序的远指针的偏移地址
// ES=指向中断子程序的远指针的段移地址
// 返回值: 无
// 注释:当子程序被调用, 它会传递以下参数:
// AX = 发生的事件 (与定义事件屏蔽相对应)
// BX = 按键状态
// CX = 当前鼠标光标X轴坐标
// DX = 当前鼠标光标Y轴坐标
// SI = 水平移动计数增量(mickey)
// DI = 垂直移动计数增量(mickey)
// 某些版本的Microsoft的驱动程序返回错误的状态─CX bit 0 表示鼠标移动
// 并且交换了SI和DI的内容
void Mouse_Unload_User_Application();
public:
static char Mouse_Cursor_Visible;
// void far User_App();
int Mouse_Reset(); // Detect And Reset Mouse Driver.
Mouse_Event Now_Event; /* Contain the mouse event and position,very important, We get Mouse Event From this global variable */
void Mouse_Show_Cursor();
void Mouse_Hide_Cursor();
void Mouse_Get_Status(Mouse_Status& Status);
void Mouse_Move_Cursor(int x,int y);
int Mouse_Get_Event();
void Mouse_Setup_Cursor(int Mode_Num=0);
// 2 -> Aim_Shape; 1-> Hand_Shape ; 0-> Arrow_Shape
MyMouse();
~MyMouse();
};
char MyMouse::Mouse_Cursor_Visible=2;
int MyMouse::MyMouse_Object_Num=0;
int MyMouse::Mouse=0;
int MyMouse::Mouse_Button_Num=0;
void MyMouse::Mouse_Setup_Cursor(int Mode_Num)
{
REGPACK regs;
regs.r_ax=9;
switch(Mode_Num)
{
case 2: regs.r_bx=7;
regs.r_cx=7;
regs.r_dx=FP_OFF(&::Aim_Shape);
regs.r_es=FP_SEG(&::Aim_Shape);
break;
case 1:
regs.r_bx=4;
regs.r_cx=0;
regs.r_dx=FP_OFF(&::Hand_Shape);
regs.r_es=FP_SEG(&::Hand_Shape);
break;
case 0:
default: regs.r_bx=0;
regs.r_cx=0;
regs.r_dx=FP_OFF(&::Arrow_Shape);
regs.r_es=FP_SEG(&::Arrow_Shape);
break;
}
intr(MOUSE_INTERRUPT,®s);
return;
}
int MyMouse::Mouse_Reset() // Detect And Reset Mouse Driver.
{
REGPACK regs;
regs.r_ax=0x0000;
intr(MOUSE_INTERRUPT,®s);
if (regs.r_ax==0xffff)
{Mouse=1;Mouse_Button_Num=regs.r_bx;}
else
Mouse=0;
return Mouse;
}
/*
int MyMouse::Mouse_Reset()
{
regs.r_ax=0x0000;
intr(MOUSE_INTERRUPT,®s);
if (regs.r_ax==0xffff)
{
Mouse_Button_Num=regs.r_bx;
return 1;
}
else
{
Mouse_Button_Num=0;
return 0;
}
}
*/
void MyMouse::Mouse_Show_Cursor()
{
// if(Mouse_Cursor_Visible==1) return;
if (Mouse)
{
regs.r_ax=0x0001;
intr(MOUSE_INTERRUPT,®s);
}
Mouse_Cursor_Visible=1;
}
void MyMouse::Mouse_Hide_Cursor()
{
// if(!Mouse_Cursor_Visible) return;
if (Mouse)
{
regs.r_ax=0x0002;
intr(MOUSE_INTERRUPT,®s);
}
Mouse_Cursor_Visible=0;
}
void MyMouse::Mouse_Get_Status(Mouse_Status& Status)
{
if (Mouse)
{
regs.r_ax=0x0003;
intr(MOUSE_INTERRUPT,®s);
Status.Mouse_x=regs.r_cx;
Status.Mouse_y=regs.r_dx;
Status.Mouse_Button_Status=regs.r_bx & 0x0007;
}
}
void MyMouse::Mouse_Setup_User_Application(void far User_App(),unsigned Event_Mask)
{
REGPACK regs;
if (Mouse)
{
unsigned Sega=FP_SEG(User_App),Offa=FP_OFF(User_App);
regs.r_ax=0x000c;
regs.r_cx=Event_Mask; // 0x1F;
regs.r_dx=Offa;
regs.r_es=Sega;
intr(MOUSE_INTERRUPT,®s);
// regs.r_ax=0x0003;
// intr(MOUSE_INTERRUPT,®s);
// Mouse_Get_Status(Mouse_Now_Status);
}
}
void MyMouse::Mouse_Unload_User_Application()
{ REGPACK regs;
if (Mouse)
{
regs.r_ax=0x000c;
regs.r_cx=0;
intr(MOUSE_INTERRUPT,®s);
}
}
void MyMouse::Mouse_Move_Cursor(int x,int y)
{
if (Mouse)
{
regs.r_ax=0x0004;
regs.r_cx=x;
regs.r_dx=y;
intr(MOUSE_INTERRUPT,®s);
}
}
int MyMouse::Mouse_Get_Event()
{
Now_Event=::Event;
(::Event).Event_ID=0;
return Now_Event.Event_ID;
}
MyMouse::MyMouse()
{
if(!MyMouse_Object_Num)
{ Mouse_Reset();
if(!Mouse)
{
// clrscr();
printf("\n Mouse Driver Not Found,Installing A MicroSoft Mouse Driver,Please!");
exit(0);
}
Mouse_Setup_User_Application(::User_App,0x1F);
// Mouse_Setup_Cursor(1);
}
MyMouse_Object_Num++;
Now_Event.Event_ID=0;
::Click_Time[0]=::Click_Time[1]=::Click_Time[2]=0;
return;
}
MyMouse::~MyMouse()
{
MyMouse_Object_Num--;
if(!MyMouse_Object_Num)
Mouse_Unload_User_Application();
return;
}
/*
int far Is_Here(int x,int y,int x0,int y0)
{
int X=0,Y=0;
X=x-x0;
Y=y-y0;
if(X<0)X=-X;
if(Y<0)Y=-Y;
if( -Here_Range<=X&&X<=Here_Range&&-Here_Range<=Y&&Y<=Here_Range)
return 1;
return 0;
}
*/
void far User_App()
{
unsigned Mevent=_AX,Mstatus=_BX;
int Mx=_CX,My=_DX;
if(User_App_Running) return;
if(Mouse_Locked) return;
// OldEvent=2;
/*if(Event.Event_ID==2)
OldEvent=Event.Event_ID;*/
User_App_Running=1;
unsigned long NewTime;
if(Mevent&_Mouse_Move_)
{
Event.Event_ID=_Mouse_Move_;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
User_App_Running=0;
return;
}
else
{
if(Mevent&_L_Button_Down_)
{
Event.Event_ID=_Mouse_Button_Down_;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Old_M_y=Event.Mouse_y;
Event.Button_Status=Mstatus;
Event.Which_Button=_L_Button_;
Old_Event_Mask=Mevent;
Old_M_y=My;
Old_M_x=Mx;
User_App_Running=0;
return;
}
if(Mevent&_R_Button_Down_)
{
Event.Event_ID=_Mouse_Button_Down_;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
Event.Which_Button=_R_Button_;
Old_Event_Mask=Mevent;
Old_M_y=My;
Old_M_x=Mx;
User_App_Running=0;
return;
}
if(Mevent&_M_Button_Down_)
{
Event.Event_ID=_Mouse_Button_Down_;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
Event.Which_Button=_M_Button_;
Old_Event_Mask=Mevent;
Old_M_y=My;
Old_M_x=Mx;
User_App_Running=0;
return;
}
if(Mevent&_L_Button_Up_)
{
if(Old_Event_Mask&_L_Button_Down_&&Is_Here(Mx,My,Old_M_x,Old_M_y))// &&Old_M_x==Mx&&Old_M_y==My)
{ NewTime=*((unsigned long far *)0x0000046cl);
if(OldEvent==2&&((NewTime-Click_Time[0])<=DBclick_Delay)&&Is_Here(Mx,My,DB_Old_x,DB_Old_y))
{ Event.Event_ID=_Mouse_Button_DBclick_;Click_Time[0]=0;OldEvent=0;}
else
{Event.Event_ID=_Mouse_Button_Click_;::Click_Time[0]=NewTime;OldEvent=2;DB_Old_x=Mx;DB_Old_y=My;}
}
else
Event.Event_ID=_Mouse_Button_Up_;
Old_Event_Mask=0;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
Event.Which_Button=_L_Button_;
User_App_Running=0;
return;
}
if(Mevent&_R_Button_Up_)
{
if(Old_Event_Mask&_R_Button_Down_&&Is_Here(Mx,My,Old_M_x,Old_M_y))// Old_M_x==Mx&&Old_M_y==My)
{ /*
Event.Event_ID=_Mouse_Button_Click_;
*/
NewTime=*((unsigned long far *)0x0000046cl);
if(OldEvent==2&&((NewTime-Click_Time[1])<=DBclick_Delay)&&Is_Here(Mx,My,DB_Old_x,DB_Old_y))
{ Event.Event_ID=_Mouse_Button_DBclick_;Click_Time[1]=0;OldEvent=0;}
else
{Event.Event_ID=_Mouse_Button_Click_;Click_Time[1]=NewTime;OldEvent=2;DB_Old_x=Mx;DB_Old_y=My;}
}
else
Event.Event_ID=_Mouse_Button_Up_;
Old_Event_Mask=0;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
Event.Which_Button=_R_Button_;
User_App_Running=0;
return;
}
if(Mevent&_M_Button_Up_)
{
if(Old_Event_Mask&_M_Button_Down_&&Is_Here(Mx,My,Old_M_x,Old_M_y))// Old_M_x==Mx&&Old_M_y==My)
{
/*Event.Event_ID=_Mouse_Button_Click_;*/
NewTime=*((unsigned long far *)0x0000046cl);
if(OldEvent==2&&((NewTime-Click_Time[2])<=DBclick_Delay)&&Is_Here(Mx,My,DB_Old_x,DB_Old_y))
{ Event.Event_ID=_Mouse_Button_DBclick_;Click_Time[2]=0;OldEvent=0;}
else
{Event.Event_ID=_Mouse_Button_Click_;Click_Time[2]=NewTime;OldEvent=2;DB_Old_x=Mx;DB_Old_y=My;}
}
else
Event.Event_ID=_Mouse_Button_Up_;
Old_Event_Mask=0;
Event.Mouse_x=Mx;
Event.Mouse_y=My;
Event.Button_Status=Mstatus;
Event.Which_Button=_M_Button_;
User_App_Running=0;
return;
}
}
}
#endif