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

方法如下:为屏幕建立一个虚拟屏幕,即在内存中开辟一片空间,用于存放屏幕信息。若将欲送到屏幕上的内容先送到虚拟屏幕(以下简称虚屏)中,然后将虚屏内容复制到物理屏幕上,
  ┌──────┐ 写入┌────┐ 写入┌────┐
  │欲显示的信息├──> 虚拟屏幕 ├──> 物理屏幕│
  └──────┘ └────┘ └────┘

1、在320X200X256下,可通过下面两条指令
VDCBuf=new (unsigned char)(320*200);
(a).memset(VDCBuf,RED,320*200);
(b).for ( i = 0 ; i < 200 ; i++)
movedata(FP_SEG(&(VDCBuf[i*320])),FP_OFF(&(VDCBuf[i*320])),0xA000,i*320,320);
将整个屏幕初始化为红色,
2、请问由于在800X600X256下存在分页,如何将通过虚拟屏幕将物理屏幕初始化为红色

搜索更多相关主题的帖子: 缓冲区 物理 屏幕 内存 困惑 
2006-11-08 16:41
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
去下个VBE标准文档看看吧,要不GOOGLE一下吴进以前写的相关文章,了解换页的概念。
2006-11-08 18:31
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
谢谢一笔苍穹,我先查一查吴进相关的文章。

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-11-08 19:53
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 

恩,我当时也是靠吴进网站里的那几篇文章引发的兴趣入的门,可惜他的站点早就关闭了。不过网上应该还是能搜到。

2006-11-09 10:24
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 

以下是我从网上好不容易google的,
#include<conio.h>
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include <dos.h>
#include <stdlib.h>
#define VBE320X200X256 0X13
#define VBE640X480X256 0X101
#define VBE800X600X256 0X103
#define VBE1024X768X256 0X105
class VIEW //显示类
{
char *video,_video_; //虚拟屏幕内存指针
unsigned short g_cur_vbe_page; //引用neo变量
public:
VIEW(); //本类构造函数
~VIEW(); //本类析构函数
void InitGraph(void); //初始化显示模式
void CloseGraph(void); //关闭图形模式
void set_vbe_page(int page); //引用neo函数
void BitBlt(); //将虚拟屏幕的内容写至物理屏幕上
void PutPixel(int x,int y,int color); //指定颜色画点
void HLine(int x,int y,int color); //画横线
};

VIEW::VIEW()
{
GuiInitGraph(); //初始化图形显式模式
_video_=(char *)malloc(800*600*sizeof(char)); //为虚拟屏幕分配内存
video = _video_;
}

VIEW::~VIEW() //本类析构函数,自动执行
{
free(video); //释放虚拟屏幕所用内存
GuiCloseGraph(); //初始化屏幕为文本状态
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//显存换页函数 引用neo函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void VIEW:: set_vbe_page(int page)
{
if (g_cur_vbe_page != page)
{
_BX = 0;
_DX = g_cur_vbe_page = page;
_AX = 0x4F05;
__int__(0x10);
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//初始化屏幕为800X600X256
/////////////////////////////////////////////////////////////////////////////////////////////////
void VIEW::GuiInitGraph(void)
{
_AX = 0x4F02;
_BX = VBE800X600X256;
__int__(0x10);
if(_AH != 0)
{
puts("Can't Initialize the graphics mode!");
exit(1);
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//关闭图形模式函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void VIEW::GuiCloseGraph(void)
{
_AX = 0x4F02;
_BX = 0x03;
__int__(0x10);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//按指定颜色画点到虚拟屏幕
/////////////////////////////////////////////////////////////////////////////////////////////////
void VIEW::PutPixel(int x, int y,int color)
{
if(x<=799 &&y<=599)
{
video=_video_+y*800+x; //移动虚拟屏幕指针
*video=color=c; //写入颜色代码并改变当前颜色
}
video=_video_; //恢复虚拟屏幕指针
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//虚拟屏幕800X600送物理屏幕函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void VIEW::BitBlt() //屏幕刷新函数
{
unsigned char i;
unsigned short *VIDEO=(unsigned short *)(0xA000<<4); //显存指针

video=_video; //恢复虚拟屏幕指针
for(i=0;i<14;i++)
{
set_vbe_page(i); //选择显存页面
memcpy(VIDEO,video,65536); //从虚拟屏幕拷贝64k数据到显存
video+=32768; //虚拟屏幕指针后移
}
set_vbe_page(14); //选择最后一页
memcpy(VIDEO,video,42496); //写入最后一页数据
video=_video; //恢复虚拟屏幕指针
}


void main()
{
VIEW vga; //创建控制指针

for (int i=0;i<800;i++)
for (int j=0;j<600;j++)
vga.PutPixel(i,j,WHITE);//从虚屏用白色点填充
vga.BitBlt(); //送到物理屏幕
getch();
getch();
}

一笔苍穹,上面的程序怎么无法实现800X600X256的屏幕上满屏显示白色呢?


多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-11-09 17:03
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
呵呵,里面还有NEO的痕迹。
_video_=(char *)malloc(800*600*sizeof(char));这句在TC\BC下是申请不到的,你也不检查一下就拿着指针用了。
2006-11-09 17:31
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 
一笔苍穹:
1、 件扩展名为*.CPP时,可以采用
_video_= new ( char)[800*600]; // 为虚拟屏幕分配内存
if (_video_f==NULL) // 内存分配失败
{
exit(1);
}
那么在扩展名为*.C时,该如何分配呢?我试过如果使用
_video_=(char *)malloc(800*600*sizeof(char));
不可靠,该如何办呢?
2、如何将虚拟屏幕_video_写到物理屏幕呢?
  如果每次往物理屏幕送1行=800个像素,采用movedata()函数,有可能进行换页,我不知道该如何处理。
  如果每次往物理屏幕送10行=8000个像素,采用movedata()函数,又该如何处理。

多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-11-10 09:01
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
你的什么编译器啊?
2006-11-10 10:44
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 

TC++3.0 for dos/BC3.1++ for dos

、如何将虚拟屏幕_video_写到物理屏幕呢?
  如果每次往物理屏幕送1行=800个像素,采用movedata()函数,有可能进行换页,我不知道该如何处理。
for (int i=0;i<600;i++)
movedata(source_seg,source_off,dest_seg,dest_off,800);
但是换页时该如何处理呢?我看到过《RockCarry工作室》的陈凯发表过虚拟缓冲区送显示缓冲区相关的文章。


多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2006-11-10 11:37
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
如果是TC++/BC++的话,你的代码:
_video_= new ( char)[800*600]; // 为虚拟屏幕分配内存
if (_video_f==NULL) // 内存分配失败
{
exit(1);
}
同样是不可靠的,一个基本的事实,DOS在实模式下每调用一次new或malloc只能申请到最多64KB的空间,你用TC++/BC++在普通情况下是无法一次性申请到800X600合400多KB的空间的,你也许会想到将这468KB的空间分开申请,那我还要告诉你一个失望的消息:DOS下一般情况下你能使用的自由空间只有640KB,你的程序本身就要占个几十KB,一个虚拟屏幕就要400多KB,加一块就是500多KB,DOS一般还要加载一些常驻程序像鼠标的驱动光驱驱动什么的,哪怕是它什么都不加载把这640K全给你,你也只剩下100K左右的空间了,省着点用吧——做图形程序的人都知道100KB是多么的微不足道。对了,记得让程序在大模式或紧凑模式下编译,不然你还无福享用这全部的640KB空间。现在你能知道比尔·盖茨在DOS刚诞生时说的那句名言:“640K对于任何用户都已经足够了…”是多么可笑和滑稽了吧?
好了,无奈归无奈,但解决方案还是要给一些的:
上策:别用TC/BC了,最好是连DOS都别碰了,LINUX或WINDOWS吧,脱离苦海,逃出阿鼻狱,阿弥陀佛……
中策:别用TC/BC了,Microsoft C也别碰了,DJGPP或WatcomC吧,保护模式,无内存限制,善哉善哉……
下策:还是用TC/BC,使用扩展扩充内存,可以访问16M内存,去查查XMS/EMS的资料吧,要不就直接用NEO中的头文件NEMS.H和XMS.H,里面有需要的基本函数,接口说明参考NEO的使用文档。等你了解完了这些后,你可以做出你上面要的东西,但却发现又淊入了一个泥潭。

[此贴子已经被作者于2006-11-10 12:21:29编辑过]

2006-11-10 12:18
快速回复:800X600X256 虚拟缓冲区送显示缓冲区的困惑
数据加载中...
 
   



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

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