主题:Tc2.0下的鼠标控制
jywzzz
[专家分:1020] 发布于 2004-04-20 16:27:00
这两天看c的中断,于是把以前用vb做的东西都一个一个翻译过来,不用再去想新的idear,感觉很好。下面是一个tc里面用到鼠标的程序,另外用到了前人做俄罗斯方块的部分函数(其实对时钟中断,我是一点不懂)。程序很短,不过效果还可以。
#include<stdio.h>
#include<graphics.h>
#include<dos.h>
#include<conio.h>
#define TIMER 0x1c
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
int TimerCounter=0;
void interrupt ( *oldhandler)(__CPPARGS);
void interrupt newhandler(__CPPARGS){
TimerCounter++;
oldhandler();
}
void SetTimer(void interrupt (*IntProc)(__CPPARGS)){
oldhandler=getvect(TIMER);
disable();
setvect(TIMER,IntProc);
enable();
}
void CloseTimer(){
disable();
setvect(TIMER,oldhandler);
enable();
}
void mshow(){
union REGS ireg,oreg;
ireg.x.ax=1;
int86(0x33,&ireg,&oreg);
}
void getmxy(double *x,double *y){
union REGS ireg,oreg;
ireg.x.ax=3;
int86(0x33,&ireg,&oreg);
*x=oreg.x.cx*1.0;
*y=oreg.x.dx*1.0;
}
resetp(int x,int y,int a,int b){
cleardevice();
setcolor(1);
rectangle(10,10,629,339);
line(x,y,a,b);
setcolor(4);
rectangle(a-5,b-5,a+5,b+5);
setcolor(2);
pieslice(x,y,0,360,10);
setcolor(1);
}
void main(void){
int gdriver=EGA,gmode=EGAHI,key;
double ax,ay,vx,vy,px,py,mx,my;
int curpage=0;
initgraph(&gdriver,&gmode,"d:\\software\\turboc2");
vx=0.0,vy=0.0,px=getmaxx()/2.0,py=getmaxy()/2.0,ax=ay=0;
mshow();
getmxy(&mx,&my);
setbkcolor(15);
setfillstyle(SOLID_FILL,2);
setactivepage(curpage);
resetp((int)px,(int)py,(int)mx,(int)my);
setvisualpage(curpage);
SetTimer(newhandler);
while(1){
if(kbhit())break;
if(TimerCounter>1){
TimerCounter=0;
getmxy(&mx,&my);
px=px+vx;
py=py+vy;
if(px>=629 || px<=10)vx=-vx;
if(py>=339 || py<=10)vy=-vy;
vx=vx*0.97+ax;
vy=vy*0.97+ay;
ax=(mx-px)*0.01;
ay=(my-py)*0.01;
curpage=curpage==0?1:0;
setactivepage(curpage);
resetp((int)px,(int)py,(int)mx,(int)my);
setvisualpage(curpage);
}
}
CloseTimer();
}
回复列表 (共12个回复)
沙发
jywzzz [专家分:1020] 发布于 2004-04-20 16:31:00
再帖上对鼠标各个方面的控制。
就是用0x33中断,然后各种不同的输入、输出。
int Mouse_Reset(){
union REGS ireg,oreg;
ireg.x.ax=0;
int86(0x33,&ireg,&oreg);
return oreg.x.ax;
}
int Mouse_GetType(){
union REGS ireg,oreg;
ireg.x.ax=0;
int86(0x33,&ireg,&oreg);
return oreg.x.bx;
}
void Mouse_Show(){
union REGS ireg,oreg;
ireg.x.ax=1;
int86(0x33,&ireg,&oreg);
}
void Mouse_Hide(){
union REGS ireg,oreg;
ireg.x.ax=2;
int86(0x33,&ireg,&oreg);
}
int Mouse_GetButton(){
union REGS ireg,oreg;
ireg.x.ax=3;
int86(0x33,&ireg,&oreg);
return oreg.x.bx;
}
int Mouse_LeftBtnPress(){
int btn;
btn=Mouse_GetButton();
if(btn & LEFTBTN)
return 1;
else
return 0;
}
int Mouse_RightBtnPress(){
int btn;
btn=Mouse_GetButton();
if(btn & RIGHTBTN)
return 1;
else
return 0;
}
int Mouse_MidBtnPress(){
int btn;
btn=Mouse_GetButton();
if(btn & MIDBTN)
return 1;
else
return 0;
}
void Mouse_GetXY(int *x,int *y){
union REGS ireg,oreg;
ireg.x.ax=3;
int86(0x33,&ireg,&oreg);
*x=oreg.x.cx;
*y=oreg.x.dx;
}
void Mouse_GetTextXY(int *x,int *y){
Mouse_GetXY(x,y);
*x=*x/8+1;
*y=*y/8+1;
}
void Mouse_SetXY(int x,int y){
union REGS ireg,oreg;
ireg.x.ax=4;
ireg.x.cx=x;
ireg.x.dx=y;
int86(0x33,&ireg,&oreg);
}
void Mouse_SetTextXY(int x,int y){
Mouse_SetXY((x-1)*8,(y-1)*8);
}
void Mouse_SetXRange(int minx,int maxx){
union REGS ireg,oreg;
ireg.x.ax=7;
ireg.x.bx=minx;
ireg.x.dx=maxx;
int86(0x33,&ireg,&oreg);
}
void Mouse_SetYRange(int miny,int maxy){
union REGS ireg,oreg;
ireg.x.ax=8;
ireg.x.cx=miny;
ireg.x.dx=maxy;
int86(0x33,&ireg,&oreg);
}
int Mouse_GetMove(int *x,int *y){
union REGS ireg,oreg;
ireg.x.ax=11;
int86(0x33,&ireg,&oreg);
*x=oreg.x.cx;
*y=oreg.x.dx;
return(*x || *y);
}
另外,哪位朋友有对时钟中断详细的介绍,能贴一下最好。(就是setvect,getvect和其相关函数的具体使用方法)
板凳
rkyyt [专家分:10] 发布于 2004-04-21 22:38:00
函数名: setvect
功 能: 设置中断矢量入口
用 法: void setvect(int intr_num, void interrupt(*isr)());
3 楼
rkyyt [专家分:10] 发布于 2004-04-21 22:40:00
函数名: getvect
功 能: 取得中断向量入口
用 法: void interrupt(*getvect(int intr_num));
程序例:
#include <stdio.h>
#include <dos.h>
void interrupt get_out(); /* interrupt prototype */
void interrupt (*oldfunc)(); /* interrupt function pointer */
int looping = 1;
int main(void)
{
puts("Press <Shift><Prt Sc> to terminate");
/* save the old interrupt */
oldfunc = getvect(5);
/* install interrupt handler */
setvect(5,get_out);
/* do nothing */
while (looping);
/* restore to original interrupt routine */
setvect(5,oldfunc);
puts("Success");
return 0;
}
void interrupt get_out()
{
looping = 0; /* change global variable to get out of loop */
}
4 楼
jywzzz [专家分:1020] 发布于 2004-04-21 23:06:00
说实话,你的例子我看不懂,就是看懂了,这个例子也太例子了。
我看我还是找本乱七八糟的书来看看吧。
依然很感谢你。
5 楼
山路幽灵 [专家分:0] 发布于 2004-04-21 23:47:00
试着运行过,觉得好像很慢,可能是自己的机子问题吧![em2]
6 楼
PC串口通信 [专家分:0] 发布于 2004-04-25 10:14:00
搂主你好,看了你的程序是有关C的底层硬件编程,最近我也在做PC与单片机之间的串口通信的C编程,能不能请教一下PC中断是怎么进行的阿?如果搂主比较忙,能不能推荐以下有什么书可以查到有关C的硬件编程阿,谢谢啦[em20][em2]
7 楼
woshihanjin [专家分:2510] 发布于 2004-04-25 11:45:00
其实上面的鼠标实例还有一个最重要的东西没有给出,就是自定义鼠标中断,记忆里好像是33h中断的1ch号功能吧,这样鼠标一有动静就会调用自定义的中断处理函数,否则以前面的方法如果碰到一个密集运算,老鼠就挂了。
8 楼
chen_xi [专家分:40] 发布于 2004-04-25 20:22:00
hao
9 楼
jywzzz [专家分:1020] 发布于 2004-04-25 22:21:00
5楼的朋友说很慢,是的,因为TimerCounter>1,该成TimerCounter>0就好了。这和机器没有关系。
6楼的朋友,我很抱歉,我也没有这样的资料啊。我看的一些零碎的东西,也是多年前的了,估计你找不到这样的东西了。
7楼的朋友,你总是指出我的错误,呵呵,如果你知道的话,就告诉我吧。
这两天要考试,好累,昨天又停电,郁闷哦……(化悲痛为力量
10 楼
woshihanjin [专家分:2510] 发布于 2004-04-25 22:43:00
有本叫中断大全的书,大概5MB左右(太大了,我的空间传不上去,不然给大家一个下载连接),讲得非常之详细,鼠标、SVGA、DPMI、XMS、CDROM、ACPI,基本上所有的硬件资料都有
我来回复