Talking about EGA Emulation

β€œWhat parts of EGA are you emulating? Only the color space and (more or less) resolution, or do you do something deeper?”

Great question! It's actually been long enough that I had forgotten a lot of the work I did on EGA emulation. The original project stored the frame buffer data in bit-planes the way it was done on the hardware. The code for this is on a public github repo:

#if defined(EGA_MODE_0Dh)
#define EGA_RES_WIDTH 320
#define EGA_RES_HEIGHT 200
#define EGA_TEXT_CHAR_WIDTH 8
#define EGA_TEXT_CHAR_HEIGHT 8
#define EGA_PIXEL_HEIGHT 1.2f
#define EGA_PIXEL_WIDTH 1.00f
#elif defined(EGA_MODE_10h)
#define EGA_RES_WIDTH 640
#define EGA_RES_HEIGHT 350
#define EGA_TEXT_CHAR_WIDTH 8
#define EGA_TEXT_CHAR_HEIGHT 14
#define EGA_PIXEL_HEIGHT 1.37f
#define EGA_PIXEL_WIDTH 1.00f
#else
#error segalib: You must define a video mode in config.h
#endif

#define EGA_COLORS 64
#define EGA_COLOR_UNDEFINED (EGA_COLORS)
#define EGA_COLOR_UNUSED (EGA_COLORS + 1)
#define EGA_PALETTE_COLORS 16
#define EGA_TEXT_RES_WIDTH (EGA_RES_WIDTH / EGA_TEXT_CHAR_WIDTH)
#define EGA_TEXT_RES_HEIGHT (EGA_RES_HEIGHT / EGA_TEXT_CHAR_HEIGHT)
#define EGA_PIXELS (EGA_RES_WIDTH * EGA_RES_HEIGHT)
#define EGA_BYTES (EGA_PIXELS / 8)
#define EGA_PLANES 4
#define EGA_IMAGE_PLANES (EGA_PLANES + 1)

#define MAX_IMAGE_WIDTH 1024
#define MAX_IMAGE_HEIGHT 768

I cringe a little looking back at some of this because I didn't know what I was doing and definitely wasn't doing a lot of hardware-specific memory layout work which is what I would do on an emulation project now. I didn't know about ImGui back then and still wanted my dream of in-engine dev tools so I actually made EGA-compliant developer tools you could switch into for editing the map and writing lua, it was a little wild!

Drawing a bitplaned asset onto an existing framebuffer was a giant pain because you had to shift the asset to align to the correct place. It was actually a performance problem on modern hardware and I ended up needing to do it much smarter than I originally thought. I remember digging up a lot of old posts and articles about techniques people used like this for storing animations inside the bitplanes.

I can't find it now but I remember an article from a developer talking about storing 8 copies of their assets each one shifted by one so you could always just render the aligned asset and never have to do the shifting logic!

When I resurrected the old EGA project into the new engine now powering Chronicles, I vastly simplified the back-end for convenience. Now the frame buffer is just 1 byte per pixel which only stores the palette index. In the end the only restrictions on the current generation of the game is the palette and color logic because even the resolution is apocryphal and text rendering is now completely arbitrary :host-joy:

In the end it's purely an aesthetic restriction now but I did once upon a time aim to have a pure backend implementation!

#gamedev #chron4

| 🌐 | πŸ™‹β€ | @britown@blog.brianna.town