我的编程环境是一个MS-DOS仿真器,我正在使用Assembly 16位编程。
我使用的是常规文本模式,可以在其中打印字符并使用属性。
在屏幕的一部分上,我每秒绘制许多字符,其中数千个字符,这创建了一个漂亮的动画。
关键是,为了创建动画,首先我必须删除旧的动画,基本上是将空格字符打印大约1000次。(!)现在,因为我正在执行此操作,所以每当我重新绘制动画时,都会出现一个轻微的闪烁问题,这很明显而且很烦人。
我正在使用视频服务来完成所有输出和动画处理。因此,我的第一个念头是以某种方式停止刷新屏幕,重新绘制所有内容,然后让屏幕自己继续刷新。
因为此过程每秒发生很多次,而且必须多次发生,所以我发现任何其他清洁方法都没有很大帮助。
基本的问题是,即使只是一瞬间,您也正在向用户展示他们本不希望看到的东西,即一个空白的,充满空格的屏幕。这就是导致闪烁的原因。您可以通过使用单个BIOS调用(例如INT 10h AX = 0600h)更快地擦除屏幕来改善此问题,但是更好的解决方案是仅向用户显示他们所看到的内容。
一种方法是更改代码,以便在绘制新框架时完全覆盖旧框架。这样就无需擦除屏幕。因此,例如,与其在屏幕上的不同位置处跳转来绘制文本,不如从左上角开始并从左到右,从上到下绘制文本。打印空格以将光标从一个位置移到另一个位置。假设您只有两种功能可以使用,一种将光标移动到屏幕的左上角,另一种打印字符并前进光标。
如果那太困难了,您可以使用屏幕外的缓冲区来做您现在正在做的事情。擦除屏幕外的缓冲区,在其上绘制文本,然后显示它。这样,用户将永远不会看到他们本来就不会看到的已擦除屏幕。您可以在内存中创建屏幕外缓冲区,然后将其复制到屏幕上,也可以在视频内存中的页面之间切换。
在内存中使用缓冲区意味着您无法使用BIOS函数来利用它,但是根据情况,这可能会更加方便。您将使用普通的内存写操作来擦除缓冲区并绘制文本,然后将整个缓冲区复制到屏幕上。从本质上讲,这是一种完全覆盖我上面所述的所有内容的方法。
在视频页面之间进行翻转可能使您可以使用与现在相同的BIOS功能来绘制文本。也就是说,假设他们在BH中采用一个参数来指定要使用的页面。并非所有的BIOS函数都具有此功能,尤其是我之前提到的BIOS函数INT 10h,AH = 06h。您将使用两个视频页面0和1,并且需要跟踪当前哪个页面处于活动状态并向用户显示。然后,您将擦除并在非活动页面上绘制文本,完成后,您将翻动页面,使非活动页面成为活动页面。为此,您可以使用INT 10h AX = 05XX,其中XX是要激活的页码。
一种更高级的技术是直接写入视频内存。早在MS-DOS流行时,个人计算机就太慢了,以至于对于任何形式的实用动画而言,使用BIOS绘制文本通常都太慢了。取而代之的是,大多数执行此类操作的应用程序会绕过缓慢的BIOS例程,直接写入视频内存。您可以结合使用上述任何一种技术。例如,您可以在普通内存中绘制一个屏幕外缓冲区,然后使用REP MOVS指令将其复制(“ blit”)到视频内存中。
绕过BIOS的不利之处在于它使代码的可移植性降低了。例如,原始的IBM PC单色显示适配器(MDA)和彩色图形适配器(CGA)的视频内存位于不同的位置(分别为B000:0000和B800:0000)。其他不是100%与PC兼容的第三方计算机甚至更奇怪。有些不支持文本模式,BIOS将使用位图图形模式绘制文本。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句