Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I was indulging in nostalgia and remembered the first game I created, which used Mode 13h.

This mode was really simple to work with, since it was essentially just an array of bytes with an element for each pixel on the screen (using an indexed color scheme).

So I thought it might be fun to create something nowadays under these restrictions, but on modern hardware. The API could be as simple as:

public class Mode13h
{
    public byte[] VideoMemory = new byte[320 * 200];
    public Color[] Palette = new Color[256];
}

Now I'm wondering what would be the best way to get this data on the screen, using something like XNA / DirectX / OpenGL.

The only solution I could think of was to create a texture with the same size as the VideoMemory array, write the contents of VideoMemory to it every frame, then render that texture in a full screen quad with the correct aspect ratio and using point texture filtering for that retro look.

Is there a better way?

share|improve this question
    
I'm not really familiar with how Mode 13h is used. Are you manipulating individual pixels? –  Cypher Oct 6 '12 at 16:06
    
@Cypher Yes, the array maps directly to the pixels on the screen. For example, using the API above, if I did VideoMemory[323]=17 it would set the pixel at position (3,1) (because 323=3+1*320) to whatever color is stored in Palette[17]. –  David Gouveia Oct 6 '12 at 17:17
add comment

2 Answers 2

up vote 3 down vote accepted

Using OpenGL I think the best way to do it is to create a texture with the size of your buffer and updating it using glTexSubImage2D. Then you just have to render a texture quad, the filtering used should be GL_NEAREST. Also be sure to disable mipmapping to gain some performance on updates.

I wanted to do the same thing and apparently this is the best way to do it with modern hardware, plus it allows easy scaling.

There is also a library made for this, PixelToaster :

http://code.google.com/p/pixeltoaster/

share|improve this answer
    
Yeah, that's the same thing I thought. But for instance, maybe instead of writing to the texture every frame, I could use a dirty flag (or a dirty rectangle) to determine when to update the texture. What do you think? –  David Gouveia Oct 6 '12 at 17:26
    
Keeping track of dirty flags/rectangles is probably overkill. Modern GPUs can update dozens of 320x200 textures per frame without breaking a sweat. –  postgoodism Oct 7 '12 at 5:11
    
Even if you keep a dirty flag you would still have to update every frame when there's a lot of things happening, plus as postgoodism said a 320x200 texture update will unlikely create a speed issue. –  Whiskas Oct 7 '12 at 7:22
add comment

Is there a better way?

Not that I can think of. In case you were keen on using XNA to do this, here's an expansion on your idea:

public class Mode13h {
    public RenderTarget2D VideoMemory;
    public Texture2D[] Palette;
    public Texture2D[][] Pixels;

    public Mode13h() {
        this.Palette = new Texture2D[256];
        this.Pixels = new Texture2D[320][200];
        this.VideoMemory = new RenderTarget2D( GraphicsDevice, 320, 200 );

        // initialize and populate the color palette
        foreach( Texture2D color in this.Palette) {
            color= new Texture2D( GraphicsDevice, 1, 1 );
        }
        this.Palette[0].SetData<Color>( new Color[] { Color.Black} );
        // ... do the above 255 more times :P or find some way to do it in the loop

        // initialize pixels
        for( int i = 0; i < 320; i++ ) {
            for( int j = 0; j < 200; j++ ) {
                this.Pixels[i][j] = new Texture2D( GraphicsDevice, 1, 1 );
                this.Pixels[i][j] = this.Palette[0]; // default black
            }
        }
    }
}

I think you can already see where I'm going with this, but I'll spell it out just to be clear:

  • Pre-populate Palette with each of the 256 colors that will be used by the game.
  • VideoMemory is your backbuffer which represents an old-school 320x200 display.
  • Pixels is a representation of each pixel on that display.

Update Phase

After accepting input and adjusting sprite positions, you'll want to clear out your Pixels array by copying a black pixel from the Palette to each one of the many (many) Pixels. You can then modify your Pixels by copying the appropriate colored pixel references from the Palette (probably by referencing an array of sorts from your sprites -- assuming you've been-there-done-that).

Render Phase

All you have to do now is loop through all of the screen pixels in Pixels and draw them to VideoMemory, then draw VideoMemory to the game window / screen. Because everything is a Texture2D, you can use SpriteBatch which makes this a bit easier.

Possible Improvements

I'm not sure if this would help, but it might be useful to create a single texture with one pixel for each color that you want to use in your palette. Then use that single texture to derive each one of the Texture2D in Palette by using a source rectangle. That might improve rendering with SpriteBatch since you would in effect, have one texture. It may even be better to store Palette as an array of Rectangles...

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.