NES graphics editor

by Damian Yerrick

A lot of people making graphics in the style of 1980s video games want a tool that will help make their graphics conform to the limitations of the platforms. How better to enforce NES limits than to make graphics directly on the NES? This program lets you draw pictures with tiles on an NES or anything that can run an NES emulator. (Sorry, iDevice owners.) If you have an NES and a PowerPak, it also lets you preview your graphics on the real thing and adjust your palette to account for the artifacts added by the NES's primitive composite video encoder.

Using the editor

The screen is 30 rows of 32 tiles, each 8 by 8 pixels. A picture can use up to 256 different tiles. Each 2 by 2 tile (16 by 16 pixel) area can use one of four color sets in the palette. All color sets have three colors plus a shared background color.

Make a copy of one of the files in the sample_savs folder, and put it where your emulator can find it. This will depend on where your particular emulator stores saved games. For a PowerPak, .sav files can be kept anywhere on the CF card. Then run the editor. First you'll see a title screen; press Start to get to the tile picker.

Tile picker

This screen shows all 256 tiles. Use the Control Pad to select a tile, press B to select a color set, and press A to start drawing. Press Start to go to the tile editor, or press Select to show a menu that leads to the palette editor and tile optimization tools. From most other screens, you can press Select to return to this screen.

NOTE: If you started with a blank .sav file, you won't see much here until you play around in the tile editor.

Drawing with tiles

Use the Control Pad to move the cursor. Press A Button to place the selected tile, or hold A and move to place the selected tile multiple times. Press B to pick up the tile and color set under the cursor, and press B again to cycle among the four color sets with this tile. Press Select to go back to the tile picker, or hold Select and use the Control Pad to quickly select a different tile. (In a future version, the Start button will eventually do one of two interesting things.)

A display in the corner of the screen shows where the cursor is and what tile is selected. It slides out of the way when you try to draw in the area that it covers.

When you draw, nearby tiles may change colors. This is because color sets are assigned on a grid twice as large as the tile grid.

Tile editor

The tile editor shows a zoomed view of 30 tiles from the tile sheet. The thin lines on the border show the edges of a single tile. A status bar at the bottom shows where on the 128x128 pixel tile sheet the cursor is located, the number of the tile corresponding to this location, how many times this tile is used in the picture, and which color you are using.

Move the pencil cursor with the Control Pad and press A to draw. Press B to pick up the color under the pencil, and B to cycle among the four colors. To scroll the view, move the cursor near the edge. To return to the tile picker, press Select.

Palette editor

Choosing "Edit Color Palette" from the tile picker's menu shows a form for editing the backdrop color and the three colors that make up each of the four color sets. Select a color with the Control Pad, then press A to change it. Left and Right change the hue, while Up and Down change the brightness. To move to a different color, press A again, or release A if you held it while changing the color. To return to the tile picker, press Select.

If you change the background color, the menu color will change along with it to stay visible. If you change the colors of a color set that's in use, everything using that color set changes along with it. Drawing, changing colors, and drawing more will not allow you to break the NES's color limit.

Tile optimization

If you have imported a .sav file from a PPU dump, it will probably have a lot of tiles that the scene doesn't use but other scenes use. To make room for new tiles that you create, you can remove unused information. The tile picker's menu gives you several ways to do this:

Importing images

The editor stores your picture in a battery-backed 64 Kbit SRAM chip, which emulators represent as a 8192 byte .sav file. A blank .sav file and several sample pictures are included in the sample_savs folder. Once you have a .sav file, put it where your emulator or PowerPak can find it, and then start the program. The PowerPak is ideal for this because its menu lets you choose one of several .sav files before starting the editor.

Or instead of starting from a blank .sav using the tile editor, you may want to convert existing images. Several conversion tools written in Python are included. To run these, you'll need to install Python and Python Imaging Library. On Ubuntu or another Debian-based system, installing the python-imaging package will get all prerequisites:

sudo apt-get install python-imaging

If you are running Windows, you'll probably need pre-built executable versions of Python 2.7.x and Python Imaging Library for Python 2.7.

From PPU dump

FCEUX for Windows can export a 16 KiB dump of the PPU memory, which includes two pattern tables (or tile sheets), four screens, and a palette. To create this dump, from the Debug menu choose Hex Editor, then from the File menu choose Dump to File > PPU Memory. The included ppu2sav tool, which requires Python, can convert this PPU dump to a .sav file for the editor.

The PPU's displayable area is two screens tall and two screens wide, though the NES itself has only enough memory for two distinct screens: two across by one down or one across by two down, depending on how the cartridge board is configured. Games that scroll over a large map, such as Contra and Mega Man 2, continuously load newly visible portions into the area that is just offscreen. If the scene is not centered, you can change the scrolling. Scrolling is specified in 16-pixel units, the same size as the area assigned to a color set, and each screen is 16 units wide and 15 units high.

The PPU actually has two tile sheets of 256 tiles each available to it, at addresses $0000 and $1000. Usually, one is used for the background and the other for sprites. Most later games use $0000 for backgrounds and $1000 for sprites, but some early games such as Super Mario Bros. use the opposite convention. (The editor itself puts user interface graphics in $0000 and your tile sheet in $1000.) If the image appears scrambled after conversion, you can tell the converter to pull tiles from $1000 instead.

ppu2sav does not support raster effects, which are commonly used in NES games to scroll the playfield while holding the status bar still. For example, a status bar in games like Super Mario Bros. will usually be in the wrong place after conversion.

Example:

ppu2sav.py smb1_ppu.bin smb1_title.sav --chr $1000 -x 16 -y 0

From BMP or PNG

png2sav converts a tile sheet in BMP or PNG format to a .sav file. If the file is 128x128 pixels or smaller, it loads every tile into the tile sheet and creates a blank nametable. Otherwise, it's treated as a full-screen image, and duplicate tiles will be removed. The converted nametable uses color set 0; you can change the colors of screen areas within the editor by picking up tiles (B), changing their color (B repeatedly), and putting them back down (A).

sav2png renders a .sav file to a PNG using Bisqwit's NES palette. Or if you use --chr and give a color set number, it extracts the .sav's tile sheet in that color set.

Examples:

png2sav.py mysketch.png mysketch.sav
sav2png.py mysketch.sav mysketch.png
sav2png.py mysketch.sav mysketch.png --chr 0

From CHR

If you have a 4096 byte .chr file that you've been using with some other NES graphics editor, you can convert it to a .sav file by appending 4096 bytes of $00.

On Windows
copy /b kitty.chr+sample_savs/chr2sav.bin kitty.sav
On Linux and other UNIX-like systems
cat kitty.chr sample_savs/chr2sav.bin > kitty.sav

Legal

The following applies to this manual and the associated programs:

© 2012 Damian Yerrick

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved in all source code copies. This file is offered as-is, without any warranty.