我正在编写一个DOS游戏框架,以更好地学习C,并且对在旧硬件(尤其是在我一起长大的系统上)上进行编程产生了普遍兴趣。
我正在尝试实现双缓冲区系统,但是在将远指针分配给320 * 200数组时遇到了麻烦。
最初,我尝试使用malloc,但发现它只能分配64kb以下的内存。我读到您需要使用farmalloc(malloc返回NULL),并且分配正确。但是,当运行_fmemset或_fmemcpy ...时,整个系统将卡住。
backBuffer = (unsigned char far*) farmalloc(64000);
当我要交换缓冲区的时候
_fmemcpy(VGA, backBuffer, 64000);
程序正在使用小内存模型。
最佳答案
非常有趣的帖子,我也非常喜欢旧硬件。
我记得在那些日子里,使用内存复制来交换屏幕缓冲区非常缓慢,更不用说您必须等待垂直回扫期才能开始复制内存。 (我有一个裸露的VGA卡,所以也许您的硬件更好,延迟也可以接受)。
如果您有兴趣,强烈建议您阅读Michael Abrash的Mode-X专栏。
Mode-X及其派生词是Michael Abrash首次记录的替代图形模式。基本上,它们是对256色13H模式的攻击,您可以通过调整VGA卡中的某些寄存器来激活它们。
激活后,有两个很大的优点:
轻松实现双倍甚至三倍的缓冲区非常简单,因为您可以直接写入非事件缓冲区并激活它,只需更改vga卡中的寄存器即可,而无需进行内存复制! (您仍然需要等待垂直回扫,否则会有难看的闪烁)
缺点是该模式更难编程,基本上,使用模式X,现在单个内存地址已映射到四个连续像素,因此,单个像素写入实际上将一次更改四个像素。 (这对于多边形填充程序来说是很大的加速!)。
如果要更改单个像素,则必须在绘制像素之前设置一个“像素掩码”(也是VGA卡寄存器),指定四个像素中的哪个像素将受存储器写入的影响。
如果天真地做,这会很慢,因为绘制的每个像素都需要设置一个 mask 。通常,我们通常直观地倾向于从左到右,从上到下画图(因为这正是在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列的链接中详细介绍了所有涉及的步骤和注册地址。这是古老的东西,但我敢打赌,您会发现它很有趣!
干杯!
关于c - 需要帮助在Borland C++ 3.0上分配远指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12428345/