0Dh 模式下的 DOS EGA 图形编程
我正在做一些复古编程来娱乐。我想创建一个使用 EGA 图形的 DOS 游戏,但我在网上找到好的参考资料时遇到了一些麻烦。每个谈论 DOS 编程的人都假设程序员将使用模式 13h,尽管有些页面提到了其他图形模式,但我还没有找到讨论它们正确使用的页面。
这就是我现在正在尝试的工作:
//------------------------------------------------------------------------------
// DOS graphics test
//
// Thanks to the following links:
// http://gamebub.com/cpp_graphics.php
//
// Written for Digital Mars C compiler to be compiled as a DOS 16 bit binary.
//------------------------------------------------------------------------------
#include <dos.h>
#include <stdio.h>
#define SCREEN_WIDTH 320;
#define SCREEN_HEIGHT 200;
unsigned char far *vram = (unsigned char far *)0xA0000000L;
//------------------------------------------------------------------------------
void set_video_mode(unsigned char mode)
{
union REGS in, out;
in.h.ah = 0;
in.h.al = mode;
int86(0x10, &in, &out);
}
//------------------------------------------------------------------------------
void plot_pixel(unsigned int x, unsigned int y, unsigned char color)
{
// this is wrong because it's only 4 bpp not 8
vram[y * 320 + x] = color;
//vram[((y<<8)+(y<<6))+x] = color;
}
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// EGA 320 x 200 x 16
set_video_mode(0x0d);
for (unsigned char i = 0; i < 255; i++)
{
vram[i] = i;
}
//plot_pixel(10, 10, 1);
getc(stdin);
return 0;
}
如果您将 set_video_mode() 更改为采用 0x13 而不是 0x0d,则此示例代码效果很好,但就像我说的,我正在尝试在此处获取 EGA 图形,而不是 VGA。 :) 我意识到,为了做到每像素四位,我要么需要假设plot_pixel同时写入两个像素,要么做一些调整以确保我只写入我想要的四位。其实想要。
我的问题是我没有看到我期望的输出——特别是没有颜色!一切似乎都是单色的,这根本不是我想要的。在此图形模式下使用调色板的过程是否与 13h 中不同?或者我是否以某种方式调用了一种与我想要的完全不同的图形模式?非常感谢您的指导。
我认为我的编译器参数不相关,但以防万一:
..\dm\bin\dmc test.c -o test -mm
I'm doing a bit of retro programming for fun. What I want to create is a DOS game using EGA graphics but I am having a bit of trouble finding a good reference on the web. Everybody who talks about doing DOS programming assumes that the programmer will use mode 13h, and although some pages mention the other graphics modes, I haven't found one yet that discusses their proper use.
Here's what I'm trying to get working right now:
//------------------------------------------------------------------------------
// DOS graphics test
//
// Thanks to the following links:
// http://gamebub.com/cpp_graphics.php
//
// Written for Digital Mars C compiler to be compiled as a DOS 16 bit binary.
//------------------------------------------------------------------------------
#include <dos.h>
#include <stdio.h>
#define SCREEN_WIDTH 320;
#define SCREEN_HEIGHT 200;
unsigned char far *vram = (unsigned char far *)0xA0000000L;
//------------------------------------------------------------------------------
void set_video_mode(unsigned char mode)
{
union REGS in, out;
in.h.ah = 0;
in.h.al = mode;
int86(0x10, &in, &out);
}
//------------------------------------------------------------------------------
void plot_pixel(unsigned int x, unsigned int y, unsigned char color)
{
// this is wrong because it's only 4 bpp not 8
vram[y * 320 + x] = color;
//vram[((y<<8)+(y<<6))+x] = color;
}
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// EGA 320 x 200 x 16
set_video_mode(0x0d);
for (unsigned char i = 0; i < 255; i++)
{
vram[i] = i;
}
//plot_pixel(10, 10, 1);
getc(stdin);
return 0;
}
This sample code works great if you change set_video_mode() to take 0x13 instead of 0x0d, but like I said I'm trying to get EGA graphic here, not VGA. :) I realize that in order to do four bits-per-pixel I'm going to either need to assume that plot_pixel writes two pixels at the same time or do a some bit twiddling to make sure I only write the four bits that I actually want.
My problem is that I'm not seeing what I expect as output--in particular, no colors! Everything seems to be mono colored, which is not what I want at all. Is there some kind of different procedure for employing a color palette in this graphics mode than in 13h? Or have I somehow invoked a completely different graphics mode from the one I intended? Guidance would be very much appreciated.
I don't think my compiler args would be relevant, but just in case:
..\dm\bin\dmc test.c -o test -mm
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
嗯..不知道这是否是一个值得回答的问题,如果我记得的话,您需要使用
inport
,inportb
,outport
,outportb
到控制 EGA 寄存器的端口,这取自优秀的 FAQSYSW(大量材料集合,从图形演示、数学、分形到压缩),原始存档位于 此处 和此处:Hmmm..dunno if this is a worthy answer, if I recall, you need to use
inport
,inportb
,outport
,outportb
to the ports to control the EGA registers, this was taken from the excellent FAQSYSW (a vast collection of materials ranging from graphics demo, maths, fractals to compressions), the original archive was found here and here.:模式 0x0d 是基于平面的,而 0x13 则不是(无需像模式 X 那样进行特殊配置) )。您应该查看更多文档以了解如何在平面模式下工作。
Mode 0x0d is planar based while 0x13 is not (without special configuration as Mode X). You should check more document to see how to work in planar mode.
它是单色的,因为它同时写入所有四个颜色平面。正如其他答案所示,模式 D 是平面的,寄存器控制着循环写入其中的哪一个。默认情况下,它选择同时写入所有平面,因此是单声道。
例如,要选择“红色”平面和“强烈”,您可以执行以下操作:
对 VRAM 的后续写入将为写入的每个位生成一个亮红色像素(1 位 = 1 像素)。当然,颜色假设调色板没有更改默认值,您也可以这样做。
It's mono-colored because it's writing to all four color planes simultaneously. Mode D is planar, as the other answers indicate, and a register controls which of these is written to with your loop. By default, it is choosing to write to all planes simultaneously, hence the mono.
To choose the 'red' plane and 'intense', for example, you can do:
Subsequent writes to VRAM will make a bright red pixel for each bit written (1 bit = 1 pixel). The color assumes of course that the palette has not been changed from the default, which you can also do.