Turbo C使用的汇编函数 -- 鼠标管理函数

         上面2篇文章《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》和《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》给出了图形代码,本篇给出鼠标管理TC函数汇编码文件。该代码很简单,而且对速度没很高的要求,完全可用纯C/C++写,但是在DOS年代,即使速度稍有提高以及代码长度缩短,也愿意用汇编码或插入汇编;鼠标功能使用int 33h,要在程序中使用鼠标,必须安装鼠标驱动程序(指纯DOS环境),鼠标驱动一般有2种形式,一是mouse.sys,必须在DOS下的config.sys文件中安装:device=mouse.sys,另外一种是mouse.com,不必在config.sys中安装,在autoexec.bat或者其它批命令文件或者直接在DOS命令行中运行后,以TSR形式驻留内存。

/*   mouse.h  */

#ifndef    __MOUSE__
#define     __MOUSE__

extern   int  MouseFlag;

#ifdef    __cplusplus
extern   " C "  {
#endif

/*  初始化, 如鼠标存在, MouseFlag = 1, 否则 MouseFlag = 0, 返回该值  */
int  Mouse_Init( void );
/*  置鼠标位置到 X, Y  */
void  Mouse_SetXY( int  x,  int  y);
/*  取鼠标当前位置到 X, Y  */
void  Mouse_GetXY( int   * x,  int   * y);
/*  打开鼠光标  */
void  Mouse_Show( void );
/*  关闭鼠光标  */
void  Mouse_Hide( void );
/*  如鼠光标在坐标(x1, y1) - (x2, y2)内返回 1, 否则返回 0  */
int  Mouse_InBox( int  x1,  int  y1,  int  x2,  int  y2);
/*  取按钮按下信息 b = 0 左按钮, b = 1 右按钮, b = 2 中按钮  */
int  Mouse_Press( int  b);
/*  取按钮放开信息 b = 0 左按钮, b = 1 右按钮, b = 2 中按钮  */
int  Mouse_Rel( int  b);
/*  返回当前按钮状态, 有按钮按下返回非 0, 否则返回 0  */
int  Mouse_State( void );
/*  设置鼠光标类型, X, Y 为光标热点, Pattern 为光标点阵地址  */
void  Mouse_SetCursor( int  X,  int  Y,  void  far  * Pattern);

#ifdef    __cplusplus
}
#endif

#endif

 

; mouse.asm

    include    tasm_c.inc

    DATASEG

    PUBLIC    _MouseFlag

_MouseFlag    dw    
0
MouseCurFlag    dw    
0

    CODESEG

    PUBLIC    _Mouse_Init
    PUBLIC    _Mouse_SetXY
    PUBLIC    _Mouse_GetXY
    PUBLIC    _Mouse_Show
    PUBLIC    _Mouse_Hide
    PUBLIC    _Mouse_State
    PUBLIC    _Mouse_Press
    PUBLIC    _Mouse_Rel
    PUBLIC    _Mouse_InBox
    PUBLIC    _Mouse_SetCursor
;
; Mouse_Init(
void )
;
PROC    _Mouse_Init

    cmp    [word _MouseFlag], 
0
    jne    @@
1
    xor    ax, ax
    
int     33h
    cmp    ax, 
0
    je    @@
1
    mov    [_MouseFlag], bx
    xor    cx, cx
    xor    dx, dx
    mov     ax, 
4
    
int     33h
@@
1 :
    mov    ax, [_MouseFlag]
    ret
ENDP
;
void  Mouse_SetXY( int  x,  int  y)
;
PROC    _Mouse_SetXY

    ARG    x : word, y : word

    mov    cx, [x]
    mov    dx, [y]
    mov    ax, 
3
    
int     33h
    ret
ENDP
;
void  Mouse_GetXY( int   * x,  int   * y)
;
PROC    _Mouse_GetXY

    ARG    x : DPTR_, y : DPTR_

    mov    ax, 
3
    
int     33h
    LES_    bx, [x]
    mov    [ES_ bx], cx
    LES_    bx, [y]
    mov    [ES_ bx], dx
    ret
ENDP
;
void  Mouse_Show( void )
;
PROC    _Mouse_Show

    cmp    [word _MouseFlag], 
0
    je    @@
1
    cmp     [word MouseCurFlag], 
0
    jne    @@
1
    mov    ax, 
1
    
int     33h
    mov    [word MouseCurFlag], 
1
@@
1 :
    ret
ENDP
;
void  Mouse_Hide( void )
;
PROC    _Mouse_Hide

    cmp    [word _MouseFlag], 
0
    je    @@
1
    cmp     [word MouseCurFlag], 
0
    je    @@
1
    mov    ax, 
2
    
int     33h
    mov    [word MouseCurFlag], 
0
@@
1 :
    ret
ENDP
;
void  Mouse_SetCursor( int  x,  int  y,  void  far  * prttern)
;
PROC    _Mouse_SetCursor

    ARG    x : word, y : word, prttern : far ptr

    mov    ax, 
9
    mov    bx, [x]
    mov    cx, [y]
    les    dx, [dword prttern]
    
int     33h
    ret
ENDP
;
int  Mouse_State( void )
;
PROC    _Mouse_State

    mov    ax, 
3
    
int     33h
    mov    ax, bx
    ret
ENDP
;
int  Mouse_Press( int  b)
;
PROC    _Mouse_Press

    ARG    b : word

    mov    ax, 
5
    mov    bx, [b]
    
int     33h
    mov    ax, bx
    ret
ENDP
;
int  Mouse_Rel( int  b)
;
PROC    _Mouse_Rel

    ARG    b : word

    mov    ax, 
6
    mov    bx, [b]
    
int     33h
    mov    ax, bx
    ret
ENDP
;
int  Mouse_InBox( int  x1,  int  y1,  int  x2,  int  y2)
;
PROC    _Mouse_InBox

    ARG    x1 : word, y1 : word, x2 : word, y2 : word

    mov    ax, [_MouseFlag]
    cmp    ax, 
0
    je    @@
3
    mov    ax, 
3
    
int     33h
    xor    ax, ax
    mov    bx, [x1]
    cmp    bx, [x2]
    jle    @@
1
    xchg    bx, [x2]
@@
1 :
    cmp    cx, bx
    jl    @@
3
    cmp    cx, [x2]
    jg    @@
3
    mov    bx, [y1]
    cmp    bx, [y2]
    jle    @@
2
    xchg    bx, [y2]
@@
2 :
    cmp    dx, bx
    jl    @@
3
    cmp    dx, [y2]
    jg    @@
3
    mov    ax, 
1
@@
3 :
    ret
ENDP
;
    END

        上面的文件中使用的插入文件tasm_c.inc和编译文件在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》中,鼠标函数也可由C++(Trubo C++或者Borland C++)直接调用。如果有人喜欢OO,正好我发现还有个C++的鼠标汇编文件,一并贴在下面供参考,不过其中的函数都是static的:

//   mouse.hpp

#ifndef    __MOUSE_HPP
#define     __MOUSE_HPP

const      int
    
//  定义鼠标按钮状态常量
    MO_LEFT_PRESS     =   - 256 ,     //  左边按钮按下
    MO_RIGHT_PRESS     =   - 257 //  右边按钮按下
    MO_LEFT_REL     =   - 258 ,     //  左边按钮放开
    MO_RIGHT_REL     =   - 259 ,     //  右边按钮放开
    MO_LEFT_DOUBLE     =   - 260 ,     //  左边按钮双击
    MO_RIGHT_DOUBLE     =   - 261 ,     //  右边按钮双击
    MO_STATE     =   - 262 ;     //  鼠标拖动

class     Mouse
{

public :

  
//  初始化, 如鼠标存在, 返回 1, 否则返回 0
   static   int  Init( void );
  
//  置鼠标位置到 X, Y
   static   void  SetXY( int  x,  int  y);
  
//  返回鼠光标当前的位置
   static   void  GetXY(  int   & x,  int   & y );
  
//  返回鼠标驱动程序安装状态, 1 已安装, 0 未安装
   static   int  DriveFlag();
  
//  打开鼠光标
   static   void  Show( void );
  
//  关闭鼠光标
   static   void  Hide( void );
  
//  如鼠光标在坐标(x1, y1) - (x2, y2)内返回 1, 否则返回 0
   static   int  InBox( int  x1,  int  y1,  int  x2,  int  y2);
  
//  如鼠光标在文本坐标(Row1, Col1) - (Row2, Col2)内返回 1, 否则返回 0
   static   int  InTextBox( int  Row1,  int  Col1,  int  Row2,  int  Col2);
  
//  设置鼠光标类型, X, Y 为光标热点, Pattern 为光标点阵地址
   static   void  SetCursor( int  X,  int  Y,  void  far  * Pattern);
  
//  返回鼠标按钮状态, 如鼠标不存在或未动作, 返回 0, 否则返回状态值(见状态常量)
   static   int  GetMouse();

};

#endif

      下面是鼠标功能C++函数汇编码文件,其中可以看到C++函数名称管理的方式,这个文件没包括在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》的MAKEFILE中,必须单独编译:

; mouse.asm

    include    tasm_c.inc

MO_LEFT_PRESS    equ    
- 256
MO_RIGHT_PRESS    equ    
- 257
MO_LEFT_REL    equ    
- 258
MO_RIGHT_REL    equ    
- 259
MO_LEFT_DOUBLE    equ    
- 260
MO_RIGHT_DOUBLE    equ    
- 261
MO_STATE    equ    
- 262

    PUBLIC    @Mouse@Init$qv
    PUBLIC    @Mouse@SetXY$qii
    PUBLIC    @Mouse@Show$qv
    PUBLIC    @Mouse@Hide$qv
    PUBLIC    @Mouse@InBox$qiiii
    PUBLIC    @Mouse@InTextBox$qiiii
    PUBLIC    @Mouse@SetCursor$qiinv
    PUBLIC    @Mouse@GetMouse$qv
    PUBLIC    @Mouse@DriveFlag$qv
IF LDATA
    PUBLIC    @Mouse@GetXY$qmit1
ELSE
    PUBLIC    @Mouse@GetXY$qrit1
ENDIF

    DATASEG

MouseFlag    dw    
0
MouseCurFlag    dw    
0
MouseTime    dd    
0

    CODESEG

PROC    @Mouse@Init$qv

    mov    ax, [word MouseFlag]
    or    ax, ax
    jnz    @@
1
    
int     33h
    or    ax, ax
    jz    @@
1
    xor    cx, cx
    xor    dx, dx
    mov     ax, 
4
    
int     33h
    mov    ax, 
1
    mov    [MouseFlag], ax
@@
1 :
    ret
ENDP

PROC    @Mouse@SetXY$qii

    ARG    x : word, y : word

    cmp    [word MouseFlag], 
0
    je    @@
1
    mov    cx, [x]
    mov    dx, [y]
    mov    ax, 
4
    
int     33h
@@
1 :
    ret
ENDP

PROC    @Mouse@Show$qv

    cmp    [word MouseFlag], 
0
    je    @@
1
    cmp     [word MouseCurFlag], 
0
    jne    @@
1
    mov    ax, 
1
    
int     33h
    mov    [word MouseCurFlag], 
1
@@
1 :
    ret
ENDP

PROC    @Mouse@Hide$qv

    cmp    [word MouseFlag], 
0
    je    @@
1
    cmp     [word MouseCurFlag], 
0
    je    @@
1
    mov    ax, 
2
    
int     33h
    mov    [word MouseCurFlag], 
0
@@
1 :
    ret
ENDP

PROC    @Mouse@SetCursor$qiinv

    ARG    x : word, y : word, prttern : far ptr
    cmp    [word MouseFlag], 
0
    je    @@
1
    mov    ax, 
9
    mov    bx, [x]
    mov    cx, [y]
    les    dx, [dword prttern]
    
int     33h
@@
1 :
    ret
ENDP

PROC    @Mouse@InBox$qiiii

    ARG    x1 : word, y1 : word, x2 : word, y2 : word

    cmp    [word MouseFlag], 
0
    jz    @@
3
    mov    ax, 
3
    
int     33h
    mov    ax, [x2]
    mov    bx, [x1]
    cmp    bx, ax
    jle    @@
1
    xchg    bx, ax
@@
1 :
    cmp    bx, cx
    jg    @@
3
    cmp    ax, cx
    jl    @@
3
    mov    ax, [y2]
    mov    bx, [y1]
    cmp    bx, ax
    jle    @@
2
    xchg    bx, ax
@@
2 :
    cmp    bx, dx
    jg    @@
3
    cmp    ax, dx
    jl    @@
3
    mov    ax, 
1
    jmp    
short  @@ 4
@@
3 :
    xor    ax, ax
@@
4 :
    ret
ENDP

PROC    @Mouse@InTextBox$qiiii

    ARG    Row1 : word, Col1 : word, Row2 : word, Col2 : word

    cmp    [MouseFlag], 
0
    jz    @@
3
    mov    ax, 
3
    
int     33h
    mov    bx, cx
    mov    ax, [Row2]
    cmp    ax, [Row1]
    jge    @@
1
    xchg    ax, [Row1]
@@
1 :
    mov    cl, 
3
    shl    ax, cl
    add    ax, 
7
    cmp    ax, dx
    jl    @@
3
    mov    ax, [Row1]
    shl    ax, cl
    cmp    ax, dx
    jg    @@
3
    mov    ax, [Col2]
    cmp    ax, [Col1]
    jge    @@
2
    xchg    ax, [Col1]
@@
2 :
    shl    ax, cl
    add    ax, 
7
    cmp    ax, bx
    jl    @@
3
    mov    ax, [Col1]
    shl    ax, cl
    cmp    ax, bx
    jg    @@
3
    mov    ax, 
1
    jmp    
short  @@ 4
@@
3 :
    xor    ax, ax
@@
4 :
    ret
ENDP

IF LDATA

PROC    @Mouse@GetXY$qmit1

ELSE

PROC    @Mouse@GetXY$qrit1

ENDIF

    ARG     x : DPTR_, y : DPTR_
    mov    ax, 
3
    
int     33h
    LES_    bx, [x]
    mov    [ES_ bx], cx
    LES_    bx, [y]
    mov    [ES_ bx], dx
    ret
ENDP

PROC    @Mouse@DriveFlag$qv

    mov    ax, [MouseFlag]
    ret
ENDP

PROC    @Mouse@GetMouse$qv

    mov    ax, [MouseFlag]
    or    ax, ax
    jz    @@
5
    xor    bx, bx
    mov    ax, 
5
    
int     33h
    mov    ax, MO_LEFT_PRESS
    or    bx, bx
    jnz    @@
3
    mov    bx, 
1
    mov    ax, 
5
    
int     33h
    mov    ax, MO_RIGHT_PRESS
    or    bx, bx
    jnz    @@
3
    xor    bx, bx
    mov    ax, 
6
    
int     33h
    or    bx, bx
    jz    @@
1
    mov    ax, MO_LEFT_REL
    jmp    
short  @@ 5
@@
1 :
    mov    bx, 
1
    mov    ax, 
6
    
int     33h
    jz    @@
2
    mov    ax, MO_RIGHT_REL
    jmp    
short  @@ 5
@@
2 :
    mov    ax, 
3
    
int     33h
    xor    ax, ax
    test    bx, 
3
    jz    @@
5
    mov    ax, MO_STATE
    jmp    
short  @@ 5
@@
3 :
    push    ax
    mov    ah, 2ch
    
int     21h
    pop    ax
    sub    dx, [word MouseTime]
    sbb    cx, [word MouseTime
+ 2 ]
    or    cx, cx
    jnz    @@
4
    cmp    dx, 
30
    jg    @@
4
    sub    ax, 
4
    mov    [word MouseTime], cx
    mov    [word MouseTime
+ 2 ], cx
    jmp    
short  @@ 5
@@
4 :
    add    [word MouseTime], dx
    adc    [word MouseTime
+ 2 ], cx
@@
5 :
    ret
ENDP
;
    END

        下一篇给出一个XMS内存管理文件代码。

        再次声明,这几篇文章的代码是1995年前的东西,用现在的眼光去看它们,还不知道是不是C函数,只能供初学者们借鉴参考。至于是否有错误,我就不得而知了,不过,我以前使用时,没出过什么问题。有错误或建议,请来信:maozefa@hotmail.com

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值