cp03.docx

上传人:b****7 文档编号:10592859 上传时间:2023-02-21 格式:DOCX 页数:26 大小:306.50KB
下载 相关 举报
cp03.docx_第1页
第1页 / 共26页
cp03.docx_第2页
第2页 / 共26页
cp03.docx_第3页
第3页 / 共26页
cp03.docx_第4页
第4页 / 共26页
cp03.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

cp03.docx

《cp03.docx》由会员分享,可在线阅读,更多相关《cp03.docx(26页珍藏版)》请在冰豆网上搜索。

cp03.docx

cp03

 

0、预备知识

0.1开发平台:

DosBox+WatcomC

①文档下载

②软件下载

假定把上述压缩包解压到D:

\

双击D:

\DosBoxWc\wc.exe进入dosbox

可以看到DosBox中显示的当前文件夹为c:

\watcom\project

请注意此文件夹是虚拟的,实际对应的物理路径为:

D:

\DosBoxWc\watcom\project

0.2如何编辑源程序?

推荐使用第三方编辑器如editplus(下载链接:

),也可以用watcomC自带的vi编辑器。

写好的程序应放在D:

\DosBoxWc\watcom\project内。

0.3如何编译?

WCL386hello.c

0.4如何运行?

hello

若错误信息太多,可以打开hello.err查看。

0.5如何调试?

调试前要对源程序重新编译,编译命令如下:

WCL386/d2hello.c

再输入调试命令:

WD/tr=rsihello

调试按键:

F10stepover执行一步,不跟踪到函数内部

F8traceinto执行一步,跟踪到函数内部

F4userscreen观察程序的输出结果

某行左侧的[]处点击鼠标可以设一个断点

0.6多个.c文件如何整合编译成一个.exe?

先建立1.c,2.c

再建立makefile,其内容如下:

12.exe:

1.c2.c

wcl386/fe=12.exe1.c2.c

最后输入以下命令进行build:

wmake

 

一、坐标系统及graphics图形库中定义的全局变量

二、文本模式(textmode)编程指南

DosBox刚运行时显卡的工作模式就是文本模式;

要让显卡工作在图形模式的话,必须调用函数initgraph();若要从图形模式返回文本模式,则应该调用函数closegraph()或text_mode()或textmode(C80);

例1:

程序a.c在屏幕(0,0)处输出一个蓝色背景红色前景的字母'A',在屏幕(1,0)处输出一个绿色背景白色前景的字母'B'。

 

请注意,文本模式下,8位颜色值中的高4位为背景色,低4位为前景色,所以当设定蓝底红字时,颜色值应该等于(BLUE<<4)+RED=(1<<4)+4=0x14。

例2:

程序b.c输出2000个黑色背景红色前景的'A'。

 

三、图形模式(graphicsmode)编程指南

3.18bit图形模式

1个点对应显存的1个字节,每个点最多有256种颜色变化。

例3:

程序c.c画一条红色水平线。

#include

#include

main()

{

intdriver=0,mode=VESA_1024x768x8bit;

char*p;

intx=100,y=100,i;

initgraph(&driver,&mode,"");

p=_vp+y*_width+x;

for(i=x;i<600-x+1;i++)

{

*p++=RED;//或写成*p++=4;

}

getchar();

}

 

程序c.c;(100,100)-(600,100)画一条红色水平线

 

8bit图形模式下的颜色编号与颜色的对应关系(如4对应红色)与文本模式类似,具体请查阅头文件graphics.h中enumCOLORS的定义或主页文档中的相关内容。

例4:

程序256color.c可以把全部256种颜色画出来:

 

 

3.224bit图形模式

1个点对应显存的3个字节,每个点的颜色有224种变化。

以下示意图展示了VESA_1024x768x24bit模式下,如何在(0,0)处画了一个红点,在(x,y)处画一个青点:

 

程序24bit0.c、24bit1.c、24bit2.c、24bit3.c功能完全一样,都以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

但它们实现的过程有所不同。

其中24bit3.c是最简单的,它直接调用bar()函数来画矩形;24bit2.c则是调用putpixel()函数画矩形中的每一个点;24bit1.c是通过语句p[y][x]=c画矩形中的每一个点;24bit0.c是通过语句

*p=(*p&0xFF000000)|color;

画矩形中的每一个点,上述语句的的执行过程可以用如下示意图描述:

 

 

例5:

程序24bit0.c使用指针写显存画点,以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

#include

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

intx,y;

longcolor=0x0000FFFF;

long*p;

initgraph(&driver,&mode,"");

for(y=100;y<=300;y++)

{

for(x=200;x<=400;x++)

{

p=(long*)(

_vp+(y*_width+x)*

(_color_bits/8)

);

*p=(*p&0xFF000000)|color;

}

}

getchar();

closegraph();

}

程序24bit0.c

 

例6:

程序24bit1.c使用二维结构数组写显存画点,以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

#include

typedefstruct

{

charblue;

chargreen;

charred;

}RGB;

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

intx,y;

RGBc={0xFF,0xFF,0x00};

RGB(*p)[1024];

initgraph(&driver,&mode,"");

p=(RGB(*)[1024])_vp;

for(y=100;y<=300;y++)

{

for(x=200;x<=400;x++)

{

p[y][x]=c;//此语句相当于以下三句

//p[y][x].blue=c.blue;

//p[y][x].green=c.green;

//p[y][x].red=c.red;

}

}

getchar();

closegraph();

}

程序24bit1.c

 

例7:

程序24bit2.c调用函数putpixel()画点,以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

#include

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

intx,y;

longcolor=0x0000FFFF;

initgraph(&driver,&mode,"");

for(y=100;y<=300;y++)

{

for(x=200;x<=400;x++)

{

putpixel(x,y,color);//调用画点函数

}

}

getchar();

closegraph();

}

程序24bit2.c

 

例8:

程序24bit3.c调用函数bar(),以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

#include

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

longcolor=0x0000FFFF;

initgraph(&driver,&mode,"");

//设定填充的模式及颜色

setfillstyle(SOLID_FILL,color);

bar(200,100,400,300);//调用画实心矩形函数

getchar();

closegraph();

}

程序24bit3.c

 

3.332bit图形模式

1个点对应显存的4个字节,每个点的颜色有224种变化。

程序32bit.c也是以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

例9:

程序32bit.c在32bit图形模式下使用二维结构数组画点,以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

 

#include

typedefstruct

{

charblue;

chargreen;

charred;

charzero;

}RGB;

main()

{

intdriver=0,mode=VESA_1024x768x32bit;

intx,y;

RGBc={0xFF,0xFF,0x00,0x00};

RGB(*p)[1024];

initgraph(&driver,&mode,"");

p=(RGB(*)[1024])_vp;

for(y=100;y<=300;y++)

{

for(x=200;x<=400;x++)

{

p[y][x]=c;

}

}

getchar();

closegraph();

}

程序32bit.c

 

由于例9程序中的RGB结构成员的长度加起来刚好是4字节,因此完全可以用long类型来取代RGB结构,修改后的程序32bitx.c如下所示:

例10:

程序32bitx.c在32bit图形模式下使用二维long型数组画点,以(200,100)为左上角,以(400,300)为右下角画一个实心的青色矩形。

#include

main()

{

intdriver=0,mode=VESA_1024x768x32bit;

intx,y;

longc=0x0000FFFF;

//red=0x00,green=0xFF,blue=0xFF

long(*p)[1024];

initgraph(&driver,&mode,"");

p=(long(*)[1024])_vp;

for(y=100;y<=300;y++)

{

for(x=200;x<=400;x++)

{

p[y][x]=c;

}

}

getchar();

closegraph();

}

程序32bitx.c

 

四、图片输出

4.1显示8bitbmp图片

调用函数load_8bit_bmp()可以在指定坐标位置显示一张256色bmp图片。

 

例11:

程序8bitbmp.c调用函数load_8bit_bmp()在坐标(0,0)显示一张图片pic256.bmp,再在坐标(200,200)显示另一张图片hello.bmp。

程序8bitbmp.c及配套图片文件打包下载链接:

#include

#include

main()

{

intx,y;

intdriver=0,mode=VESA_1024x768x8bit;

initgraph(&driver,&mode,"");

load_8bit_bmp(0,0,"pic256.bmp");

load_8bit_bmp(200,200,"hello.bmp");

getchar();

closegraph();

}

程序8bitbmp.c

 

4.2显示24bitbmp图片

例12:

程序24bitbmp.c先定义了一个用户自定义函数load_24bit_bmp(),再在函数main()中调用此自定义函数于坐标(0,0)处显示一张24bitbmp图片pic.bmp。

程序24bitbmp.c及配套图片文件打包下载链接:

 

#include

#include

#include

intload_24bit_bmp(intx,inty,char*filename)

{

FILE*fp=NULL;

byte*p=NULL;/*pointertoalineofbmpdata*/

byte*vp=_vp+(y*_width+x)*(_color_bits/8);

dwordwidth,height,bmp_data_offset,bytes_per_line,offset;

inti;

p=malloc(1024L*3);/*memoryforholdingalineofbmpdata*/

if(p==NULL)/*cannotallocateenoughmemoryfordrawing1line*/

gotodisplay_bmp_error;

fp=fopen(filename,"rb");

if(fp==NULL)/*cannotopenbmpfile*/

gotodisplay_bmp_error;

fread(p,1,0x36,fp);/*readBMPhead*/

if(*(word*)p!

=0x4D42)/*checkBMPsignature*/

gotodisplay_bmp_error;/*notaBMPfile*/

if(*(word*)(p+0x1C)!

=24)

gotodisplay_bmp_error;/*nota24-bit-colorBMPfile*/

width=*(dword*)(p+0x12);

height=*(dword*)(p+0x16);

bmp_data_offset=*(dword*)(p+0x0A);

fseek(fp,bmp_data_offset,SEEK_SET);/*skipBMPhead*/

bytes_per_line=(width*3+3)/4*4;/*mustbemultipleof4*/

for(i=height-1;i>=0;i--)/*drawfrombottomtotop*/

{

fread(p,1,bytes_per_line,fp);/*readalineofbmpdata*/

offset=i*1024*3;

memcpy(vp+offset,p,width*3);

}

free(p);

fclose(fp);

return1;

display_bmp_error:

if(p!

=NULL)

free(p);

if(fp!

=NULL)

fclose(fp);

return0;

}

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

initgraph(&driver,&mode,"");

load_24bit_bmp(0,0,"pic.bmp");

getchar();

closegraph();

}

程序24bitbmp.c

 

五、文字输出

5.1文本模式下的字符输出

文本模式下只能输出英文,不能输出中文。

如果不考虑输出的坐标位置,则可以调用printf()、puts()输出字符串;如果要在指定坐标位置输出字符串,则可以先调用函数gotoxy()把光标定位到指定位置,再调用函数puts()输出字符串。

例13:

程序text1.c调用gotoxy()控制输出坐标,先在坐标(1,1)处输出字符串"Hello,Tom!

",再在坐标(2,2)处输出字符串"Hello,Jerry"。

#include

#include

main()

{

clrscr();//清屏

gotoxy(1,1);

puts("Hello,Tom!

");

gotoxy(2,2);

puts("Hello,Jerry!

");

getchar();

}

程序text1.c

 

请注意gotoxy()函数中,横坐标及纵坐标都是以1为基的,即(1,1)相当于实际坐标(0,0)。

在文本模式下,除了调用gotoxy(),还可以使用视频指针_vp来控制输出的坐标及内容。

例14:

程序text2.c使用指针vp控制输出坐标及颜色和内容,先在坐标(0,0)处输出黑色背景白色前景的字符串"Hello,Tom!

",再在坐标(1,1)处输出蓝色背景红色前景的字符串"Hello,Jerry"。

#include

#include

voidputsxy(intx,inty,char*s,charcolor)

{

char*vp=_vp+(y*_width+x)*2;

inti=0;

while(s[i]!

='\0')

{

*vp=s[i];

*(vp+1)=color;

vp+=2;

i++;

}

}

main()

{

clrscr();

putsxy(0,0,"Hello,Tom!

",BLACK<<4|WHITE);

putsxy(1,1,"Hello,Jerry!

",BLUE<<4|RED);

getchar();

}

程序text2.c

 

5.2图形模式下的字符输出

5.2.1图形模式下的英文输出

图形模式下可调用outtextxy()在指定坐标位置输出一个英文字符串。

例15:

程序outtext.c在坐标(100,100)处输出白色字符串"Hello,Tom!

",再在坐标(200,200)处输出红色字符串"Hello,Jerry!

"。

#include

#include

main()

{

intdriver=0,mode=VESA_1024x768x24bit;

initgraph(&driver,&mode,"");

//默认颜色为白色

outtextxy(100,100,"Hello,Tom!

");

setcolor(0xFF0000);//设置颜色为红色

//其中red=0xFF,green=0x00,blue=0x00

//注意图形模式下的颜色不能使用RED、GREEN、BLUE

//等常数,而应该用RGB成份进行定义

outtextxy(200,200,"Hello,Jerry!

");

getchar();

closegraph();

}

程序outtext.c

 

请注意,outtextxy()输出字符串的颜色是指前景色,该颜色由setcolor()函数指定。

outtextxy()并不描绘字符串的背景,也就是说setbkcolor()函数指定的背景色对outtextxy()无任何影响。

另外,outtextxy()是按8*16点阵输出字符,即字体大小是固定的。

5.2.2图形模式下的中文输出

图形模式下可以自己编程读取汉字的点阵字库描出16*16个点。

例16:

程序hz.c读取点阵字库hzk中"我"字的16*16点阵共32字节信息并在屏幕中间位置画出该字。

程序hz.c及相关的字库文件hzk打包下载链接:

程序hz.c通过画一个4*4的方块来描绘一个点,因此实际上把汉字放大了4倍。

但是,放大以后的汉字呈明显的锯齿形。

为了克服点阵汉字不能放大的缺陷,我们可以使用TTF曲线字库来输出汉字。

其中快速输出可以通过调用函数get_ttf_text_pic()及draw_picture()实现,慢速输出可以通过调用函数out_ttf_text_xy()实现。

例17:

程序ttftest.c演示了TTF字体的快速输出及慢速输出两种方式。

程序ttftest.c及配套字库打包下载链接:

 

六、声音输出

6.1扬声器输出

例18:

程序music.c演示了如何控制杨声器发声,演奏一首歌。

程序music.c下载链接:

 

6.2声卡输出

例19:

程序sound.c演示了如何调用函数play_wave()及play_midi()输出wav波形文件及midi音乐文件。

程序sound.c及配套声音文件打包下载链接:

 

七、输入

7.1键盘输入

charx;

scanf("%c",&x);

x=getchar();

上述两个函数在输入一个字符时需要敲回车表示输入的结束;输入的符号会显示在屏幕上;一些特殊的键无法输入如上下左右方向键。

函数bioskey()可以代替上述函数,并且克服以上3个不足之处。

intkey;

key=bioskey(0);

其中key是一个16位整数。

若当前键盘缓冲区是空的,则执行bioskey(0)会等待用户敲键;若当前键盘缓冲区非空,则执行bioskey(0)会把键盘缓冲区中的键读走,不会等待用户输入。

bioskey

(1)用来检测键盘缓冲区是否为空,若缓冲区为空,则bioskey

(1)返回0,否则返回非零。

什么是键盘缓冲区?

CPU能在运行程序时处理外部中断(interrupt)。

当用户按下某个键时,键盘会向CPU发出一个中断请求,此时CPU会暂停正在运行的程序而转去处理键盘中断,处理的结果是把当前按住的键读走并存放到键盘缓冲区中。

键盘缓冲区是一个队列(queue),相当于一个数组。

例20:

程序blkctrl1.c演示了如何用bioskey(0)控制键移动屏幕上的一个方块。

程序blkctrl1.c下载链接:

例21:

程序blkctr12.c演示了如何用bioskey

(1)检测键盘缓冲区从而控制方块做随机运动。

程序blkctrl2.c下载链接:

除了使用bioskey()控制键盘外,还可以用键盘中断来控制键盘。

使用键盘中断不仅可以读取bioskey()无法读取的键如Ctrl、Shift、Alt、CapsLock等,而且可以在用户按下某个键的瞬间作出实时响应。

例22:

程序blkctr13.c演示了如何用键盘中断控制方块的移动。

程序blkctrl3.c下载链接:

 

7.2鼠标输入

鼠标要用到int33h中断

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1