This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Using gimpscript to automate my CHR graphics asset pipeline

Using gimpscript to automate my CHR graphics asset pipeline
by on (#139624)
Just thought I'd share a development technique I recently worked out, in case it's useful to others.

You probably already know about tepple's Python Image Library-based png/gif/etc -> CHR converter from his NROM template. This is great, because it means you can generate your pattern tables / CHR ROM banks using any modern image editing program that can produce 4-color indexed images in modern formats.

Personally I use the GIMP for my pixel-pushing -- I make extensive use of visual grids, layers (collapsed before exporting), cubic interpolated rotations, etc. GIMP's native file format is called XCF, and it's what will save all of the GIMP-specific "metadata" about your image in addition to the pixels themselves, like layout grids, layers, undo history, and more.

So, in terms of my project's git repository, the XCF files are like the "source" files, and the resulting PNGs are like intermediate binary files produced from the source files, and the CHR files are the final binary output. Only the XCF source files are checked in and versioned, since the PNGs and CHRs are derived.

Up to now, this required a manual step of exporting the XCF image to PNG from within GIMP. But ideally the whole source -> binary pipeline should be automated by my Makefile, and dependency-aware.

So I wrote this little bash script that uses GIMP's LISPy scripting language to automatically export an XCF file to PNG from the shell:

set -o nounset

GIMP="$(which gimp)"
if [ ! -x "$GIMP" ]; then
    echo "$0: \`gimp' not found on PATH."
    exit 1


if [ ! -r "$INFILE" ]; then
    echo "$0: Input file not found or not readable: $INFILE" >&2
    exit 1

(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE \"$INFILE\" \"$INFILE\")))
      (drawable (car (gimp-image-get-active-layer image))))
 (file-png-save RUN-NONINTERACTIVE image drawable \"$OUTFILE\" \"$OUTFILE\" 0 9 0 0 0 1 1)
 (gimp-image-delete image))

(gimp-quit 0)"

# Go
"$GIMP" -i -b "$GIMP_LISP"

So now my Makefile looks like this:
# bin/bmp2nes is tepple's converter
chr/sprites.chr: chr/sprites.png bin/bmp2nes
        bin/bmp2nes -i chr/sprites.png -o chr/sprites.chr

# bin/xcf2png is the above script
chr/sprites.png: chr/sprites.xcf bin/xcf2png
        bin/xcf2png chr/sprites.xcf chr/sprites.png

# My main object file depends on the sprites.chr file because it .incbins it
main.o: main.s chr/sprites.chr
        # ... run ca65, etc.

So now I can happily do all of my sprite editing in the GIMP with infinite undo and fancy tools, and just ctrl-s when I'm done. The next time I run make, it detects that the PNG needs to get regenerated, the CHR rom binary gets regenerated, any assembly modules that depend on it get reassembled, and the .nes file gets re-linked together, all automatically. Boom!
Re: Using gimpscript to automate my CHR graphics asset pipel
by on (#141394)
This is really slick! My workflow has been similar to what you describe (Gimp, Makefiles) but with a different png -> chr tool. Having to do the xcf -> png export has always been a pain, and led to my gimp files needing to live in a different folder structure outside of my main repo. I'm looking forward to integrating your export script and having everything live in one place!