NES Graphic Converters

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NES Graphic Converters
by on (#69886)
I normally just use YY-CHR as it's quick and easy for doing simple stuff but I really would like to make my graphics/fonts in a more modern way (there are plenty of 'pixel editors' out there these days). However, conversion of the graphics files to a NES format seems to still leave a lot to be desired. Especially if you're not a Windows user.

I've tried (again) to make Tepples's bmp2tiles tool work but getting anything built with the allegro library on an up-to-date version of OSX seems almost impossible (at the very least it uses up the very last drop of my patience). That's not an attack on Tepples by the way.

I know he was planning to update some of those tools to Python (was it?) but I don't know if he got around to doing that. That would be great.

Alternatively, surely someone could write one? A plain-old C/C++ cross platform conversion tool. It can't be that difficult for anyone with a modicum of knowledge, can it?

:?
Re: NES Graphic Converters
by on (#69887)
neilbaldwin wrote:
I know he was planning to update some of those tools to Python (was it?) but I don't know if he got around to doing that.

Inside the distribution of Concentration Room is a converter that uses Python Imaging Library.

Quote:
Alternatively, surely someone could write one? A plain-old C/C++ cross platform conversion tool. It can't be that difficult for anyone with a modicum of knowledge, can it?

The big question: What formats would it support? The number of dependencies needed to compile an image converter depends on what image formats are supported.
Re: NES Graphic Converters
by on (#69889)
tepples wrote:
neilbaldwin wrote:
I know he was planning to update some of those tools to Python (was it?) but I don't know if he got around to doing that.

Inside the distribution of Concentration Room is a converter that uses Python Imaging Library.

Quote:
Alternatively, surely someone could write one? A plain-old C/C++ cross platform conversion tool. It can't be that difficult for anyone with a modicum of knowledge, can it?

The big question: What formats would it support? The number of dependencies needed to compile an image converter depends on what image formats are supported.


Of course. Well, if it were to be modern then indexed PNG. And that's it :)

I don't know much about graphics at all. I guess any uncompressed format that uses an indexed palette? Which would mean .GIF, .BMP and .PNG?

by on (#69893)
I wrote my own tile converter [1] as part of my build system for a game that I was experimenting with. Tile info can come from text files [2] or chunks of other chr files [2].

The source is in C. The program emits asm source meant to be input to 'ca65' for linking into the game's char-rom (or prog-rom if using char-ram).

Feel free to adapt it to your needs if you wish. Someday I'll pick that project back up and polish the tools too.

[1] https://www.ecoligames.com/svn/nes-game ... ile-maker/

[2] https://www.ecoligames.com/svn/nes-game/trunk/gfx/

by on (#69894)
I grabbed the Python tools from CR and (with minimal fiddling) I was pleasantly surprised that bmp2tiles works pretty nicely with indexed .PNGs.

Thanks Tepples :)

@clueless: I'll have a look at your stuff too. One thing that puts me off from the description is that you're outputting as assembly. Would be better to have a binary option then you could load the resulting .chr file into a nametable/map editor etc.

by on (#69895)
neilbaldwin wrote:
@clueless: I'll have a look at your stuff too. One thing that puts me off from the description is that you're outputting as assembly. Would be better to have a binary option then you could load the resulting .chr file into a nametable/map editor etc.


I suppose. However, the game that I was working on used char-ram on MMC1. I was possibly going to add compression to the output, and the compressed output would be dumped into one of the games 'RODATA' segment. Its final location would be assigned by the linker. Therefore I needed asm output for input to ca65, not a raw, n*8K chr file.

If I resume that game again (I plan to), I will probably split the tile maker off as a separate project and then add more features to it. My current project (for the 2010 minigame compo) is much simpler and I'm using yy-chr for it.

by on (#69898)
clueless wrote:
neilbaldwin wrote:
One thing that puts me off from the description is that you're outputting as assembly. Would be better to have a binary option then you could load the resulting .chr file into a nametable/map editor etc.

I suppose. However, the game that I was working on used char-ram on MMC1.

My CHR RAM projects use an .incbin statement. So do my CHR ROM projects that use an RLE nametable for the title screen. Or are you specifically targeting users of assemblers without .incbin?

Quote:
I was possibly going to add compression to the output

The "UNIX way" to do things is to make one program that does each step: one that converts PNG to CHR (e.g. the Python program that I recommended to Neil) and another that converts CHR to compressed CHR (e.g. packbits from Pin Eight NES Tools).

Quote:
and the compressed output would be dumped into one of the games 'RODATA' segment. Its final location would be assigned by the linker. Therefore I needed asm output for input to ca65, not a raw, n*8K chr file.

In ca65, you can do it like this:
Code:
.segment "RODATA"
titletiles_pkb:
  .incbin "titletiles.pkb"

by on (#69901)
I know all of that is possible (incbins included). I've repeatedly said that my tool produces asm for consumption by "ca65". What I didn't say is that it emits ".s" (raw ".db" statements) and a ".inc" file that defines all of the symbols. My chr converter allows me to remap chrs, and it auto-magically takes care of keeping all of the symbols straight. Simply doing an "incbin" of a chr file won't update all of the symbols, which are consumed by the rest of the ".s" files.

It is simply that I chose my own method when I wrote a tool for my use. I didn't expect to raise such a ruckus over it. I offered it for others to use. If they don't like it, then don't use it.

I know the "unix way". I've been a unix developer and admin for 15+ years. My personal project wasn't meant to be production quality...

by on (#69903)
You have a point: haters can "Feel free to adapt it to your needs if you wish." It's just that the debate over outputting asm vs. binary brought back memories of GBA programming, where the GNU assembler for ARM didn't have .incbin.
Re: NES Graphic Converters
by on (#69908)
neilbaldwin wrote:
Of course. Well, if it were to be modern then indexed PNG. And that's it :)

I don't know much about graphics at all. I guess any uncompressed format that uses an indexed palette? Which would mean .GIF, .BMP and .PNG?

I'm using a converter I made a while back (in Delphi, I should probably convert it to something else) that doesn't care if the source images are indexed or true color, it just cares about the final colors of the pixels. It works by using additional images, one containing all the palettes used by the tiles (one palette per row, with the first color being the palette's ID) and the other specifying what palette should be used for each tile (this is done by using the palette IDs). If you are using only one palette you don't need the "attribute" image. This was the best way I could find to use multiple palettes in my images.

A feature I miss in graphic converters is the option of encoding two-dimensional areas into consecutive tiles, but I'm not sure what's the best way to implement this (maybe use an external file to describe the 2D areas?). And also an option to encode 8x16 tiles.
Re: NES Graphic Converters
by on (#69909)
tokumaru wrote:
This was the best way I could find to use multiple palettes in my images.

I just make sure all my palettes are in the same order sky, dark, medium, light (or sky, light, medium, dark if it's better), and then draw everything in shades of black, gray, and white.

Quote:
A feature I miss in graphic converters is the option of encoding two-dimensional areas into consecutive tiles, but I'm not sure what's the best way to implement this (maybe use an external file to describe the 2D areas?). And also an option to encode 8x16 tiles.

I seem to remember that one of my converters supports "metatile width" and "metatile height" on the command line. Thus you can get your 8x16 or 8x32 for NES, or a 16x16 or 32x32 that works well for scrolling map background tiles or Genesis/GBA style 1D sprite tile mapping.
Re: NES Graphic Converters
by on (#69915)
tepples wrote:
I just make sure all my palettes are in the same order sky, dark, medium, light (or sky, light, medium, dark if it's better), and then draw everything in shades of black, gray, and white.

I used to do something similar, but looking at everything with the same palette isn't a good preview of what the end result is going to look like. I like to work with the actual colors, and having to replace them all before converting is a much biger pain than creating the palette and attribute images my converter uses.

Quote:
I seem to remember that one of my converters supports "metatile width" and "metatile height" on the command line. Thus you can get your 8x16 or 8x32 for NES, or a 16x16 or 32x32 that works well for scrolling map background tiles or Genesis/GBA style 1D sprite tile mapping.

I considered doing something like this, but that's not versatile enough. I could use the same approach I used for the palettes, and allow an extra image to describe tile groups. The dimensions of this image would be 8 times smaller than the image with the tiles, and pixels with the same color would mean tiles of the same group. This way I could even encode irregular shapes (no need to use only squares and rectangles). But what would be the best way to specify the order in which groups are encoded? Maybe the brightness of the colors used to specify the groups. I'd also need to find a way to specify the metatile dimensions for each group. Maybe I could add some meaning to the RGB values of the group colors, like R = group priority, G = metatile width, B = metatile height.

I use MS paint to draw all my sprites, because I'm not comfortable with the constraints imposed by traditional tile editors, which IMO encourage the designing of blocky graphics. So the ideas above are an attempt to use the same image for both drawing and converting, without the need to "export" (rearrange the individual tiles and replace colors) anything before conversion.

by on (#69953)
@tepples: Quick question, are your Python tools compatible with Python 3.x? I'd like to update Python (I'm currently on 2.7) but I'm aware of the situation with non-backwards-compatibility that arose with 3.x onwards.

by on (#69960)
I've developed them on Python 2.6, and as I understand it, anything that works on Python 2.6 should be easily fixed for compatibility with 3.x after a round of 2to3. Feel free to report problems here.