很有趣的帖子,我也很喜欢旧硬件。
我记得在那些日子里,使用内存副本来交换屏幕缓冲区非常缓慢,更不用说您必须等待垂直回溯期才能开始复制内存。(我有一个基本的 VGA 卡,所以也许你的硬件更好,延迟是可以接受的)。
如果您有兴趣,我强烈建议您阅读 Michael Abrash 的Mode-X专栏。
Mode-X 及其衍生物是由 Michael Abrash 首次记录的替代图形模式。基本上,它们是对 256 色 13H 模式的破解,您可以通过调整 VGA 卡中的一些寄存器来激活该模式。
一旦激活,有两个很大的优势:
- 四页显存
- 方形像素(在 320x240 的原始 ModeX 中),(绘制的圆圈看起来像一个圆圈,而不是椭圆)
实现双甚至三缓冲区是轻而易举的事,因为您可以直接写入非活动缓冲区并激活它,只需更改 vga 卡中的寄存器,根本不需要 memcopy!(还是需要等待垂直回扫,否则会出现难看的闪烁)
缺点是这种模式更难编程,基本上,模式-X 现在单个内存地址映射到四个连续像素,因此,单个像素写入实际上会一次更改四个像素。(这对于多边形填充程序来说是一个很好的加速!)。
如果要更改单个像素,则必须在绘制像素之前设置一个“像素掩码”(也是 VGA 卡寄存器),指定四个像素中的哪一个会受到内存写入的影响。
如果天真地完成,这会很慢,因为绘制的每个像素都需要设置掩码。通常我们直观地倾向于从左到右,从上到下(因为这正是视频内存在 VGA 模式 13H 上的映射方式),但我们 Mode-X 程序员了解到“旋转范例”要快得多,即,我们从上到下、从左到右绘制东西。
为什么?因为这允许我们为绘制的每一列只修改一次像素掩码!这是一些伪代码:
天真、直观的编程
pixelptr = start of screen memory
foreach row
foreach column
adjust pixel mask
write pixel value
pixelptr+= 1 // advance pointer to next pixel to the left
next
next
轮换编程模式
[Edit1:添加了必须将指针移动到下一列顶部的缺失步骤]
[Edit2:更正,我添加 320 以前进到下一行,实际上这应该除以 4,因为视频内存地址的连续增量将映射到前一个右侧的下一个四个像素组,四个-像素组]
for each column
pixelptr = start of screen memory + current column index
adjust pixel mask // same mask applies to every pixel in the same column!
for each row
write pixel value
pixelptr += (320 / 4) // advance pointer to next pixel, to the bottom
next
next
所有涉及的步骤和注册地址在我提供的 Michael Abrash 专栏的链接中都有详细说明。这是古老的东西,但我打赌你会发现它很迷人!
干杯!