| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1090 人关注过本帖
标题:帖一篇320X200X256色下双缓冲区程序,谁能移植到800X600X256色下
只看楼主 加入收藏
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
 问题点数:0 回复次数:7 
帖一篇320X200X256色下双缓冲区程序,谁能移植到800X600X256色下

// 注:程序扩展名为.CPP,必须在TC++ for dos 或BC++ for dos 下运行(TC2.0下会出错)
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <bios.h>
#include <conio.h>

#define LineSpace 2 /*行距*/
#define WinW 17*16 /*定义窗口的宽度*/
#define WinH (LineSpace+16)*7+5 /*窗口的宽度*/
#define WinX 30 /*屏幕窗口的起始坐标*/
#define WinY 30
#define BKCOLOR BLUE //开始时的背景色
#define FORECOLOR WHITE //字符前景色
#define BORLDCOLOR RED //屏幕边框色
#define DelayTime 10
#define StartUpLine '^' //上画线开始
#define StartDownLine '_' //下画线开始
#define EndUpLine 'U' //上画线结束
#define EndDownLine 'D' //下画线结束
#define SetForeColorVal 'C' //设置前景色
#define SetBkColorVal 'B' //设置背景色
#define ControlCommand '\\' //控制命令所用字符
#define ESC 0x011b
#define STYLENUM 10 //显示特技类型个数

#define MyWait() { delay(DelayTime);\
if (bioskey(1))\
{ if(bioskey(1)!=ESC) bioskey(0);\
break;\
}\
}

enum InitRetVal
{ /*初始化返回值定义*/
InitOK,
OpenASC16Error,
OpenHZK16Error,
MallocError
};


void SetShowMode(int mode) /*设置显示模式*/
{
union REGS r;

r.h.al=mode;
r.h.ah=0;
int86(0x10,&r,&r);
}


void ClearScreen(int x,int y,int w,int h,int color)
{
int i,j;

for(i=0;i<h;i++)
for(j=0;j<w;j++)
pokeb(0xa000,(y+i)*320+x+j,color);
}


unsigned int inkey(int delaytime)
{
int i;

for(i=0;i<delaytime;i++)
{
delay(1);
if (bioskey(1))
return(bioskey(0));
}
return(0);
}


class VDC
{
private :
int VDCWidth; /*虚拟屏幕内存的宽度*/
int VDCHight; /*高度*/
int ForeColor; //前景色
int BkColor; //背景色
int DownLine; //下画线
int UpLine; //上画线
unsigned char *VDCBuf; /*屏幕内存保存处*/
FILE *LibFp; //汉字库指针
FILE *AscFp; //ASC字库指针
public:
void SetBkColor(int color); //设置显示字符的背景色
void SetForeColor(int color); //设置前景色
void SetDownLineStyle(int i); //设置下画线属性
void SetUpLineStyle(int i); //设置上画线属性
int InitVDC(int w, int h,int color,int bkcolor);//初始化VDC
void CopyVDCToScreen(int x,int y,int style);//将VDC内容复制到屏幕
void ClearVDC(int x,int y,int w,int h,int color);//在VDC中清一矩形
void ClearAllVDC(int color); //清除所有的VDC
void ShowText(int x,int y,unsigned char *string);//显示字符串
void DrawPixel(int x,int y); //在VDC中,画一点
void BitBlt(int x,int y,int w,int h,int ScreenX,int ScreenY); //将VDC矩形区域复制到屏幕上
~VDC() { if(VDCBuf!=NULL) delete VDCBuf; fclose(LibFp); fclose(AscFp);}
};


void VDC::SetBkColor(int color) //设置显示字符的背景色
{
BkColor=color;
}

void VDC::SetForeColor(int color) //设置前景色
{
ForeColor=color;
}

void VDC::SetDownLineStyle(int i) //设置下画线属性
{
DownLine=i;
}


void VDC::SetUpLineStyle(int i) //设置上画线属性
{
UpLine=i;
}


/*******************************************************/
/* 函数作用:在虚拟屏幕中显示字符串 */
/* 入口参数:int x,int y, 显示的坐标 */
/* unsigned char *string, 显示的字符串 */
/*******************************************************/
void VDC::ShowText(int x,int y,unsigned char *string) /*显示的字符串*/
{
int i,j,z,s,LineNum;
unsigned char c,mode[32];
long offset;
int n,IsUse;

while(*string)
{
IsUse=0;
c=*string;
if (c==ControlCommand)
{
IsUse=1;
switch(*(string+1))
{
case StartUpLine: //上画线开始
string+=2;
UpLine=1;
break;
case EndUpLine: //结束上画线
string+=2;
UpLine=0;
break;
case StartDownLine: //开始下画线
string+=2;
DownLine=1;
break;
case EndDownLine: //结束下画线
string+=2;
DownLine=0;
break;
case SetForeColorVal: //设置前景色
ForeColor=*(string+2)-'0';
string+=3;
break;
case SetBkColorVal: //设置背景色
BkColor=*(string+2)-'0';
string+=3;
break;
case '\\': //若后一字符为'\',表示此为一个'\'
string++;
IsUse=0;
break;
default: //其它字符,则没有用到
IsUse=0;
break;
}
}
if (IsUse) continue;

if (c>0x80) /*为汉字*/
{
offset=((c-0xa1)*94+(*(string+1)-0xa1))*32L;
fseek(LibFp,offset,SEEK_SET);
fread(mode,32,1,LibFp);
string+=2;
if (x+16>VDCWidth) //若显示该汉字超过指定的宽度,则换下一行显示
{
x=0;
y+=16+LineSpace;
}
if (y>=VDCHight)
break; //若下一行起始位置达到高度,则退出
else
LineNum=(VDCHight-y>16)? 16:VDCHight-y;
//当前可显示多少行
for(j=0;j<LineNum;j++) /*将该汉字写入VDC表示的内存中*/
{
for(z=0;z<2;z++)
for(s=0;s<8;s++,x++)
if (mode[j*2+z]>>(7-s) & 1) /*对应有位为1,则用前景色表示*/
VDCBuf[VDCWidth*y+x]=ForeColor;
else //否则用背景色表示
VDCBuf[VDCWidth*y+x]=BkColor;
y++;x-=16;
}
y-=LineNum;x+=16;
}
else //为半角字符
{
fseek(AscFp,c*16,SEEK_SET);
fread(mode,1,16,AscFp);
string++;
/*取该汉字的字模*/
if (x+8>VDCWidth)
{
x=0;
y+=16+LineSpace;
}
if (y>=VDCHight)
break;
else
LineNum=(VDCHight-y>16) ? 16:VDCHight-y;
for(j=0;j<LineNum;j++)
/*将该汉字写入VDC表示的内存中*/
{
for(s=0;s<8;s++,x++)
if (mode[j]>>(7-s) & 1) /*对应有位为1,则用前景色表示*/
VDCBuf[VDCWidth*y+x]=ForeColor;
else /*否则用背景色表示*/
VDCBuf[VDCWidth*y+x]=BkColor;
y++;x-=8;
}
y-=LineNum;x+=8;
}

LineNum=(c>0x7f)? 16:8;
if (DownLine) //下画线为真,在此汉字下画线
for(i=0;i<LineNum;i++)
DrawPixel(x-LineNum+i,y+15);

if (UpLine) //上画线为真,在此汉字下画线
for(i=0;i<LineNum;i++)
DrawPixel(x-LineNum+i,y);
}
}

/**************************************************/
/* 函数作用:建立虚拟屏幕 */
/* 入口参数:w,h 屏幕的宽度和高度 */
/* color 字符前景色 */
/* bkcolor 字符背景色 */
/*************************************************/
int VDC::InitVDC( int w, int h,int color,int bkcolor)
{
LibFp=fopen("d:\\HZK16","rb");
if (LibFp==NULL)
return(OpenHZK16Error);
AscFp=fopen("d:\\ASC16","rb");
if (AscFp==NULL) //asc16不能打开
{
fclose(LibFp);
return(OpenASC16Error);
}
VDCWidth=w;
VDCHight=h;
UpLine=0;
DownLine=0;
ForeColor=color;
BkColor=bkcolor;
VDCBuf=new (unsigned char)(w*h);
if (VDCBuf==NULL) //内存分配失败
{
fclose(LibFp); //关闭打开的文件
fclose(AscFp);
return(MallocError);
}
ClearAllVDC(BkColor);
return(InitOK); //初始化成功
}

/*****************************************************/
/* 函数作用:将虚拟屏幕清一矩形区域 */
/* 入口参数:x,y 虚拟屏幕的起始坐标 */
/* w,h 矩形的宽和高 */
/* color 清后区域的色彩 */
/***************************************************/

void VDC::ClearVDC(int x,int y,int w,int h,int color)
{
int i;

for(i=0;i<h;i++)
memset(&VDCBuf[(y+i)*VDCWidth+x],color,w);
}

//将整个虚拟屏幕清成color色
void VDC::ClearAllVDC(int color)
{
memset(VDCBuf,color,VDCWidth*VDCHight);
}

/*VDC中画一点*/
void VDC::DrawPixel(int x,int y)
{
if (!(x>VDCWidth || x<0 ||y>VDCHight||y<0))
VDCBuf[y*VDCWidth+x]=ForeColor;
}


/************************************************/
/* 函数作用:将虚拟屏幕区域内容复制到屏幕上 */
/* 入口参数:x,y 虚拟屏幕的起始坐标 */
/* w,h 欲复制区域的宽度、高度 */
/* ScreenX,ScreenY 物理屏幕的起始位置 */
/************************************************/
void VDC::BitBlt(int x,int y,int w,int h,int ScreenX,int ScreenY)
{
int i;

for (i=0;i<h;i++)
movedata(FP_SEG(&(VDCBuf[(y+i)*VDCWidth+x])),
FP_OFF(&(VDCBuf[(y+i)*VDCWidth+x])),
0xa000,(ScreenY+i)*320+ScreenX,w);
}


/*****************************************************/
/* 函数作用:将虚拟屏幕的内容全部复制到物理屏幕上 */
/* 入口参数:ScreenX,ScreenY 物理屏幕的起始坐标 */
/* style 复制类型 */
/* 说 明:此类型选择时,将动态产生显示特技,若不选 */
/* 择,将快速复制屏幕上 */
/*****************************************************/
void VDC::CopyVDCToScreen(int ScreenX,int ScreenY,int style=24)
{
int i,j,scanline,w,h;

switch(style)
{
case 0: //从下向上
for (i = VDCHight -1;i>=0;i--)
{
BitBlt(0,i,VDCWidth,1,ScreenX,i+ScreenY);
MyWait();
}
break;
case 1: //从左向右
for (i = 0 ;i<VDCWidth ;i++)
{
BitBlt(i,0,1,VDCHight,ScreenX+i,ScreenY);
MyWait();
}
break;
case 2: //从上下向中央
for (i = 0 ; i<VDCHight / 2 ;i++)
{
j = VDCHight - i-1;
BitBlt( 0, i, VDCWidth, 1, ScreenX, ScreenY+i);
BitBlt( 0, j, VDCWidth, 1, ScreenX,ScreenY+ j);
MyWait();
}
break;
case 3: //由上而下成百叶窗口
scanline = 3 + random(6);
for (i = 0 ;i<scanline;i++)
for (j = i ; j<VDCHight;j+=scanline)
{
BitBlt( 0, j, VDCWidth, 1,ScreenX, ScreenY+j);
MyWait();
}
break;
case 4: //从左向右成百叶窗显示
scanline = 3 + random( 6);
for (i = 0 ;i<scanline;i++)
for(j = i ; j<VDCWidth ;j+=scanline)
{
BitBlt( j, 0, 1, VDCHight,ScreenX+j, ScreenY);
MyWait();
}
break;
case 5 : //由中央扩展到四周
j = 0;
for(i = 0 ;i<VDCHight / 2;i++)
{
BitBlt(VDCWidth/2-j,VDCHight/2-i,2*j,2*i,
ScreenX+ VDCWidth/2-j,ScreenY+VDCHight/2-i);
j = (VDCHight/2+i*VDCWidth) / VDCHight;
MyWait();
}
break;
case 6 : // 从右向左流动
for(i = 0 ;i< VDCWidth;i++)
{
BitBlt(0,0,i,VDCHight,ScreenX+VDCWidth-i,ScreenY);
MyWait();
}
break;
case 7 : //从中央同时向左右流动
for(i = 0 ;i< VDCWidth / 2;i++)
{
BitBlt(0,0,i,VDCHight,ScreenX+VDCWidth/2-i,ScreenY);
BitBlt(VDCWidth-i,0,i,VDCHight,VDCWidth/2+ScreenX,ScreenY);
MyWait();
}
break;
case 8 : //从左上角流动到右下角
i = 0;
for (j = 0 ;j<VDCWidth;j++)
{
BitBlt(VDCWidth-j,VDCHight-i,j,i,ScreenX,ScreenY);
i = (j * VDCHight+VDCWidth/2) / VDCWidth;;
MyWait();
}
break;
case 9: //成碎片显示
for (scanline=0;scanline<(VDCWidth*VDCHight/7);scanline++)
{
i=random(VDCWidth);
j=random(VDCHight);
w=random(6)+4;
h=random(6)+4;
if (i+w>=VDCWidth) w=1;
if (j+h>=VDCHight) h=1;
BitBlt(i,j,w,h,ScreenX+i,ScreenY+j);
if(kbhit()) break; /*若用户按下任意键,退出*/
}
break;
}
BitBlt(0,0,VDCWidth,VDCHight,ScreenX,ScreenY);
}


void main()
{
int start,bkcolor;
unsigned int key;
VDC vDC;
unsigned char *text=
"\\_ 长\\D\\^夜空\\U虚使我怀旧事,\
明月朗相对念母亲。父母亲爱心,柔善象碧玉,怀念怎不悲莫禁。\
长夜空虚枕冷夜半泣,遥路远碧海是我心,\\C5父母\\C7\\B4亲爱\
心。柔善象碧玉,常在心里问何日报,亲恩应该报,应该识取孝道\
。唯独我离别无abc法慰亲旁,轻弹曲子梦中送。";

int style,oldstyle,i;

if (vDC.InitVDC(WinW,WinH,FORECOLOR,BKCOLOR)!=InitOK)
{
puts("\n\7VDC init error.\n");
exit(0);
}
SetShowMode(0x13);/*设置320*200*256色模式*/
ClearScreen(0,0,320,200,WHITE); //将整个屏幕清成白色
//将欲作为窗口的矩形区域置成带投影的窗口
ClearScreen(WinX+4,WinY+4,WinW,WinH,BLACK);
//窗口四周为红边
ClearScreen(WinX-1,WinY-1,WinW+2,WinH+2,BORLDCOLOR);
//窗口为蓝色
ClearScreen(WinX,WinY,WinW,WinH,BKCOLOR);
//将虚拟屏幕背景色置成BKCOLOR
//在虚拟屏幕上显示信息
bkcolor=BKCOLOR;

while(1)
{
vDC.ShowText(0,6,text); //显示文本信息
vDC.ClearVDC(0,0,WinW,5,bkcolor);
vDC.CopyVDCToScreen(WinX,WinY,random(STYLENUM+1));
key=inkey(500);
if (key==ESC) break; //按下ESC,退出
bkcolor=random(256);
vDC.ClearAllVDC(bkcolor);
vDC.SetBkColor(bkcolor);
ClearScreen(WinX,WinY,WinW,WinH,BKCOLOR);
}
SetShowMode(0x3);
exit(0);
}

搜索更多相关主题的帖子: 缓冲区 移植 
2006-12-14 10:09
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
将虚拟屏幕的内容全部复制到物理屏幕上 有很多好处:
 1、不会产生闪烁
 2、可以制作很多特技,如:
a.从下向上显示整屏
b.从左向右
c.从上下向中央
d.由上而下成百叶窗口
e.从左向右成百叶窗显示
f.由中央扩展到四周
g.从右向左流动
h.成碎片显示

上述程序完全调试成功,粘贴后命名为Visual.CPP在TC++ for dos下即可运行。

如何移植到800X600X256下,使得800X600X256下也能使用双缓冲区呢?(可能必须使用EMS扩展)

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-12-14 10:16
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
上面的程序有误,请粘贴下面一贴的程序。

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-12-14 10:20
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <bios.h>
#include <conio.h>

#define LineSpace 2 /*行距*/
#define WinW 17*16 /*定义窗口的宽度*/
#define WinH (LineSpace+16)*7+5 /*窗口的宽度*/
#define WinX 30 /*屏幕窗口的起始坐标*/
#define WinY 30
#define BKCOLOR BLUE //开始时的背景色
#define FORECOLOR WHITE //字符前景色
#define BORLDCOLOR RED //屏幕边框色
#define DelayTime 10
#define StartUpLine '^' //上画线开始
#define StartDownLine '_' //下画线开始
#define EndUpLine 'U' //上画线结束
#define EndDownLine 'D' //下画线结束
#define SetForeColorVal 'C' //设置前景色
#define SetBkColorVal 'B' //设置背景色
#define ControlCommand '\\' //控制命令所用字符
#define ESC 0x011b
#define STYLENUM 10 //显示特技类型个数
#define MyWait() { delay(DelayTime);\
if (bioskey(1))\
{ if(bioskey(1)!=ESC) bioskey(0);\
break;\
}\
}

enum InitRetVal
{ /*初始化返回值定义*/
InitOK,
OpenASC16Error,
OpenHZK16Error,
MallocError
};

void SetShowMode(int mode) /*设置显示模式*/
{
union REGS r;

r.h.al=mode;
r.h.ah=0;
int86(0x10,&r,&r);
}

void ClearScreen(int x,int y,int w,int h,int color)
{
int i,j;

for(i=0;i<h;i++)
for(j=0;j<w;j++)
pokeb(0xa000,(y+i)*320+x+j,color);
}

unsigned int inkey(int delaytime)
{
int i;

for(i=0;i<delaytime;i++)
{
delay(1);
if (bioskey(1))
return(bioskey(0));
}
return(0);
}


class VDC
{
private :
int VDCWidth; /*虚拟屏幕内存的宽度*/
int VDCHight; /*高度*/
int ForeColor; //前景色
int BkColor; //背景色
int DownLine; //下画线
int UpLine; //上画线
FILE *LibFp; //汉字库指针
FILE *AscFp; //ASC字库指针
public:
unsigned char *VDCBuf; /*屏幕内存保存处*/
void SetBkColor(int color); //设置显示字符的背景色
void SetForeColor(int color); //设置前景色
void SetDownLineStyle(int i); //设置下画线属性
void SetUpLineStyle(int i); //设置上画线属性
int InitVDC(int w, int h,int color,int bkcolor);//初始化VDC
void CopyVDCToScreen(int x,int y,int style);//将VDC内容复制到屏幕
void ClearVDC(int x,int y,int w,int h,int color);//在VDC中清一矩形
void ClearAllVDC(int color); //清除所有的VDC
void ShowText(int x,int y,unsigned char *string);//显示字符串
void DrawPixel(int x,int y); //在VDC中,画一点
void BitBlt(int x,int y,int w,int h,int ScreenX,int ScreenY); //将VDC矩形区域复制到屏幕上
~VDC() { if(VDCBuf!=NULL) delete VDCBuf; fclose(LibFp); fclose(AscFp);}
};


void VDC::SetBkColor(int color) //设置显示字符的背景色
{
BkColor=color;
}

void VDC::SetForeColor(int color) //设置前景色
{
ForeColor=color;
}

void VDC::SetDownLineStyle(int i) //设置下画线属性
{
DownLine=i;
}


void VDC::SetUpLineStyle(int i) //设置上画线属性
{
UpLine=i;
}


/*******************************************************/
/* 函数作用:在虚拟屏幕中显示字符串 */
/* 入口参数:int x,int y, 显示的坐标 */
/* unsigned char *string, 显示的字符串 */
/*******************************************************/
void VDC::ShowText(int x,int y,unsigned char *string) /*显示的字符串*/
{
int i,j,z,s,LineNum;
unsigned char c,mode[32];
long offset;
int n,IsUse;

while(*string)
{
IsUse=0;
c=*string;
if (c==ControlCommand)
{
IsUse=1;
switch(*(string+1))
{
case StartUpLine: //上画线开始
string+=2;
UpLine=1;
break;
case EndUpLine: //结束上画线
string+=2;
UpLine=0;
break;
case StartDownLine: //开始下画线
string+=2;
DownLine=1;
break;
case EndDownLine: //结束下画线
string+=2;
DownLine=0;
break;
case SetForeColorVal: //设置前景色
ForeColor=*(string+2)-'0';
string+=3;
break;
case SetBkColorVal: //设置背景色
BkColor=*(string+2)-'0';
string+=3;
break;
case '\\': //若后一字符为'\',表示此为一个'\'
string++;
IsUse=0;
break;
default: //其它字符,则没有用到
IsUse=0;
break;
}
}
if (IsUse) continue;

if (c>0x80) /*为汉字*/
{
offset=((c-0xa1)*94+(*(string+1)-0xa1))*32L;
fseek(LibFp,offset,SEEK_SET);
fread(mode,32,1,LibFp);
string+=2;
if (x+16>VDCWidth) //若显示该汉字超过指定的宽度,则换下一行显示
{
x=0;
y+=16+LineSpace;
}
if (y>=VDCHight)
break; //若下一行起始位置达到高度,则退出
else
LineNum=(VDCHight-y>16)? 16:VDCHight-y;
//当前可显示多少行
for(j=0;j<LineNum;j++) /*将该汉字写入VDC表示的内存中*/
{
for(z=0;z<2;z++)
for(s=0;s<8;s++,x++)
if (mode[j*2+z]>>(7-s) & 1) /*对应有位为1,则用前景色表示*/
VDCBuf[VDCWidth*y+x]=ForeColor;
else //否则用背景色表示
VDCBuf[VDCWidth*y+x]=BkColor;
y++;x-=16;
}
y-=LineNum;x+=16;
}
else //为半角字符
{
fseek(AscFp,c*16,SEEK_SET);
fread(mode,1,16,AscFp);
string++;
/*取该汉字的字模*/
if (x+8>VDCWidth)
{
x=0;
y+=16+LineSpace;
}
if (y>=VDCHight)
break;
else
LineNum=(VDCHight-y>16) ? 16:VDCHight-y;
for(j=0;j<LineNum;j++)
/*将该汉字写入VDC表示的内存中*/
{
for(s=0;s<8;s++,x++)
if (mode[j]>>(7-s) & 1) /*对应有位为1,则用前景色表示*/
VDCBuf[VDCWidth*y+x]=ForeColor;
else /*否则用背景色表示*/
VDCBuf[VDCWidth*y+x]=BkColor;
y++;x-=8;
}
y-=LineNum;x+=8;
}

LineNum=(c>0x7f)? 16:8;
if (DownLine) //下画线为真,在此汉字下画线
for(i=0;i<LineNum;i++)
DrawPixel(x-LineNum+i,y+15);

if (UpLine) //上画线为真,在此汉字下画线
for(i=0;i<LineNum;i++)
DrawPixel(x-LineNum+i,y);
}
}

/**************************************************/
/* 函数作用:建立虚拟屏幕 */
/* 入口参数:w,h 屏幕的宽度和高度 */
/* color 字符前景色 */
/* bkcolor 字符背景色 */
/*************************************************/
int VDC::InitVDC( int w, int h,int color,int bkcolor)
{
LibFp=fopen("d:\\HZK16","rb");
if (LibFp==NULL)
return(OpenHZK16Error);
AscFp=fopen("d:\\ASC16","rb");
if (AscFp==NULL) //asc16不能打开
{
fclose(LibFp);
return(OpenASC16Error);
}
VDCWidth=w;
VDCHight=h;
UpLine=0;
DownLine=0;
ForeColor=color;
BkColor=bkcolor;
VDCBuf=new (unsigned char)(w*h);
if (VDCBuf==NULL) //内存分配失败
{
fclose(LibFp); //关闭打开的文件
fclose(AscFp);
return(MallocError);
}
// ClearAllVDC(BkColor);
return(InitOK); //初始化成功
}

/*****************************************************/
/* 函数作用:将虚拟屏幕清一矩形区域 */
/* 入口参数:x,y 虚拟屏幕的起始坐标 */
/* w,h 矩形的宽和高 */
/* color 清后区域的色彩 */
/***************************************************/

void VDC::ClearVDC(int x,int y,int w,int h,int color)
{
int i;

for(i=0;i<h;i++)
memset(&VDCBuf[(y+i)*VDCWidth+x],color,w);
}

//将整个虚拟屏幕清成color色
void VDC::ClearAllVDC(int color)
{
memset(VDCBuf,color,VDCWidth*VDCHight);
}

/*VDC中画一点*/
void VDC::DrawPixel(int x,int y)
{
if (!(x>VDCWidth || x<0 ||y>VDCHight||y<0))
VDCBuf[y*VDCWidth+x]=ForeColor;
}


/************************************************/
/* 函数作用:将虚拟屏幕区域内容复制到屏幕上 */
/* 入口参数:x,y 虚拟屏幕的起始坐标 */
/* w,h 欲复制区域的宽度、高度 */
/* ScreenX,ScreenY 物理屏幕的起始位置 */
/************************************************/
void VDC::BitBlt(int x,int y,int w,int h,int ScreenX,int ScreenY)
{
int i;

for (i=0;i<h;i++)
movedata(FP_SEG(&(VDCBuf[(y+i)*VDCWidth+x])),
FP_OFF(&(VDCBuf[(y+i)*VDCWidth+x])),
0xa000,(ScreenY+i)*320+ScreenX,w);
}


/*****************************************************/
/* 函数作用:将虚拟屏幕的内容全部复制到物理屏幕上 */
/* 入口参数:ScreenX,ScreenY 物理屏幕的起始坐标 */
/* style 复制类型 */
/* 说 明:此类型选择时,将动态产生显示特技,若不选 */
/* 择,将快速复制屏幕上 */
/*****************************************************/
void VDC::CopyVDCToScreen(int ScreenX,int ScreenY,int style=24)
{
int i,j,scanline,w,h;

switch(style)
{
case 0: //从下向上
for (i = VDCHight -1;i>=0;i--)
{
BitBlt(0,i,VDCWidth,1,ScreenX,i+ScreenY);
MyWait();
}
break;
case 1: //从左向右
for (i = 0 ;i<VDCWidth ;i++)
{
BitBlt(i,0,1,VDCHight,ScreenX+i,ScreenY);
MyWait();
}
break;
case 2: //从上下向中央
for (i = 0 ; i<VDCHight / 2 ;i++)
{
j = VDCHight - i-1;
BitBlt( 0, i, VDCWidth, 1, ScreenX, ScreenY+i);
BitBlt( 0, j, VDCWidth, 1, ScreenX,ScreenY+ j);
MyWait();
}
break;
case 3: //由上而下成百叶窗口
scanline = 3 + random(6);
for (i = 0 ;i<scanline;i++)
for (j = i ; j<VDCHight;j+=scanline)
{
BitBlt( 0, j, VDCWidth, 1,ScreenX, ScreenY+j);
MyWait();
}
break;
case 4: //从左向右成百叶窗显示
scanline = 3 + random( 6);
for (i = 0 ;i<scanline;i++)
for(j = i ; j<VDCWidth ;j+=scanline)
{
BitBlt( j, 0, 1, VDCHight,ScreenX+j, ScreenY);
MyWait();
}
break;
case 5 : //由中央扩展到四周
j = 0;
for(i = 0 ;i<VDCHight / 2;i++)
{
BitBlt(VDCWidth/2-j,VDCHight/2-i,2*j,2*i,
ScreenX+ VDCWidth/2-j,ScreenY+VDCHight/2-i);
j = (VDCHight/2+i*VDCWidth) / VDCHight;
MyWait();
}
break;
case 6 : // 从右向左流动
for(i = 0 ;i< VDCWidth;i++)
{
BitBlt(0,0,i,VDCHight,ScreenX+VDCWidth-i,ScreenY);
MyWait();
}
break;
case 7 : //从中央同时向左右流动
for(i = 0 ;i< VDCWidth / 2;i++)
{
BitBlt(0,0,i,VDCHight,ScreenX+VDCWidth/2-i,ScreenY);
BitBlt(VDCWidth-i,0,i,VDCHight,VDCWidth/2+ScreenX,ScreenY);
MyWait();
}
break;
case 8 : //从左上角流动到右下角
i = 0;
for (j = 0 ;j<VDCWidth;j++)
{
BitBlt(VDCWidth-j,VDCHight-i,j,i,ScreenX,ScreenY);
i = (j * VDCHight+VDCWidth/2) / VDCWidth;;
MyWait();
}
break;
case 9: //成碎片显示
for (scanline=0;scanline<(VDCWidth*VDCHight/7);scanline++)
{
i=random(VDCWidth);
j=random(VDCHight);
w=random(6)+4;
h=random(6)+4;
if (i+w>=VDCWidth) w=1;
if (j+h>=VDCHight) h=1;
BitBlt(i,j,w,h,ScreenX+i,ScreenY+j);
if(kbhit()) break; /*若用户按下任意键,退出*/
}
break;
}
BitBlt(0,0,VDCWidth,VDCHight,ScreenX,ScreenY);
}


void main()
{
int start,bkcolor;
unsigned int key;
VDC vDC;
unsigned char *text=
"\\_ 长\\D\\^夜空\\U虚使我怀旧事,\
明月朗相对念母亲。父母亲爱心,柔善象碧玉,怀念怎不悲莫禁。\
长夜空虚枕冷夜半泣,遥路远碧海是我心,\\C5父母\\C7\\B4亲爱\
心。柔善象碧玉,常在心里问何日报,亲恩应该报,应该识取孝道\
。唯独我离别无abc法慰亲旁,轻弹曲子梦中送。";

int style,oldstyle,i;

if (vDC.InitVDC(WinW,WinH,FORECOLOR,BKCOLOR)!=InitOK)
{
puts("\n\7VDC init error.\n");
exit(0);
}
SetShowMode(0x13);
ClearScreen(0,0,320,200,WHITE); //将整个屏幕清成白色
//将欲作为窗口的矩形区域置成带投影的窗口
ClearScreen(WinX+4,WinY+4,WinW,WinH,BLACK);
//窗口四周为红边
ClearScreen(WinX-1,WinY-1,WinW+2,WinH+2,BORLDCOLOR);
//窗口为蓝色
ClearScreen(WinX,WinY,WinW,WinH,BKCOLOR);
//将虚拟屏幕背景色置成BKCOLOR
//在虚拟屏幕上显示信息
bkcolor=BKCOLOR;

while(1)
{
vDC.ShowText(0,6,text); //显示文本信息
vDC.ClearVDC(0,0,WinW,5,bkcolor);
vDC.CopyVDCToScreen(WinX,WinY,random(STYLENUM+1));
key=inkey(500);
if (key==ESC) break; //按下ESC,退出
bkcolor=random(256);
vDC.ClearAllVDC(bkcolor);
vDC.SetBkColor(bkcolor);
ClearScreen(WinX,WinY,WinW,WinH,BKCOLOR);
}
SetShowMode(0x3);
exit(0);
}


多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-12-14 10:20
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
在TC这样的16位编译环境中,我觉得高分辩率与其用双缓冲,倒不如采用脏矩形。效率和兼容性都高于双缓冲。
2006-12-14 10:56
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
脏矩形如何实现,思路是什么呢?
由于屏幕很大,800X600X256甚至1024X768X256,如何记住屏幕上的每一个像素点已经更新了呢?

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-12-14 11:06
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
不用记每个像素,记弄脏了的矩形即可,gameres上有些不错的文章,云风的书上也有一些关于合并脏矩形的办法。
2006-12-14 11:56
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
双缓冲涉及的支持要有良好的内存-显存对拷机制;
脏矩形则要支持剪裁输出位图的功能。
效率则是后者更好,特别是高分辨率下,一般很少会出现整个屏幕都更新的情况。
2006-12-14 12:25
快速回复:帖一篇320X200X256色下双缓冲区程序,谁能移植到800X600X256色下
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022656 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved