aboutsummaryrefslogtreecommitdiff
path: root/img2atari
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2019-03-30 03:41:23 -0400
committerB. Watson <yalhcru@gmail.com>2019-03-30 03:41:23 -0400
commit41640fe33b90ec675cb86bf8179a44618ee1cfa5 (patch)
treeb569081fdffdeac4bf47ee79d6fc34a904840af5 /img2atari
downloadimg2atari-master.tar.gz
initial commitHEADmaster
Diffstat (limited to 'img2atari')
-rwxr-xr-ximg2atari223
1 files changed, 223 insertions, 0 deletions
diff --git a/img2atari b/img2atari
new file mode 100755
index 0000000..d52c8e2
--- /dev/null
+++ b/img2atari
@@ -0,0 +1,223 @@
+#!/usr/bin/env bash
+
+# This really is a bash script. It also seems to work in zsh, but not
+# ksh or dash. This is not a bug.
+
+SELF="$( basename $0 )"
+
+help() {
+ cat <<EOF
+$SELF - Quick & dirty image converter for Atari 8-bit computers,
+ using ImageMagick.
+
+Written by B. Watson (yalhcru@gmail.com), released under the
+WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
+
+Usage: $SELF [options] [inputfile] [outputfile]
+
+Options:
+-g <mode> Graphics mode for outputfile (8, 9, or 15, default 9)
+-f <color> Color register value for GR.8 foreground (default 0x0c)
+-b <color> Color register value for GR.8 background (default 0x00)
+-x Create standalone executable with loader and viewer
+-X Create executable with loader only as an init segment
+-a <addr> Create binary load data file, load image at <addr>
+-l <addr> Load address for -x/-X loader (default 0x0400). Give
+ address in either decimal or hex with 0x prefix.
+-d Dither. May improve results, or ruin them (YMMV). Doesn't
+ actually seem to have any visible effect.
+-r <byte> For use with -x/-X: set RAMTOP. Default 192 (>=48K Atari
+ with no cartridge or BASIC). Use 160 if BASIC will be enabled,
+ or 64 for unexpanded 400 or 600XL, etc.
+
+To write to standard output, use - as the outputfile. Reading from
+standard input is not supported.
+
+The image is scaled to fit in the desired graphics mode (with aspect
+ratio preserved) and converted to greyscale: 4 bits for -g 9, 2 bits
+for -g 15, and 1 bit (true monochrome) for -g 8.
+
+With -g 15, the loader will set the color registers to \$00 \$04 \$08
+\$0C. For raw images, you'll want to set them in whatever code you write
+that uses the raw file.
+
+Output file format depends on options given:
+
+- With no -a/-x/-X options, the output is a raw screen memory image.
+ With -g 8 or 9, this is the same as an Atari .GR8 or .GR9 file. With
+ -g 15, it's similar to a Koala .pic file, except the color registers
+ aren't saved.
+
+- With -a, the output is an Atari binary load file that loads the
+ image data at the given address, but includes no executable code. By
+ itself, this isn't very useful, but it could be used as part of a
+ multi-segment executable, or with the BLOAD command in Turbo BASIC.
+
+- With -x, the output is a standalone executable that loads and displays
+ the image in the given graphics mode, then waits for the user to press
+ a key, then exits to DOS.
+
+- With -X, the output is a binary load file that displays the image, but
+ doesn't include the "wait for keypress" code. This would be useful as
+ part of a multi-segment executable.
+EOF
+}
+
+#-n BROKEN! Narrow GTIA mode (256x192 for GR.8, 128x192 for GR.15)
+
+die() {
+ echo "$SELF: $@" 1>&2
+ exit 1
+}
+
+printbyte() {
+ printf -v tmpbyte "%02x" "$1"
+ LANG=C echo -n -e "\x$tmpbyte"
+}
+
+printword() {
+ printbyte $(( $1 % 256 ))
+ printbyte $(( $1 / 256 ))
+}
+
+printbytes() {
+ for i in "$@"; do printbyte 0x$i; done
+}
+
+GRMODE=9
+DITHER="+dither"
+RAMTOP=192
+LOADERADDR=1024
+SDMCTL=0x22
+
+if [ "$#" = "0" ]; then
+ help
+ exit 0
+fi
+
+while [ "$1" != "" ]; do
+ case "$1" in
+ "--help"|"-help"|"-h"|"-?") help ; exit 0 ;;
+ "-g") GRMODE="$2" ; shift ;;
+ "-f") FGCOLOR="$2" ; shift ;;
+ "-b") BGCOLOR="$2" ; shift ;;
+ "-x") LOADER=1; VIEWER=1 ;;
+ "-X") LOADER=1; VIEWER=0 ;;
+ "-a") IMGSTART="$2" ; shift ;;
+ "-l") LOADERADDR="$2" ; shift ;;
+ #"-n") NARROW=1; SDMCTL=0x21 ;;
+ "-n") die "narrow mode not yet supported" ;;
+ "-d") DITHER="" ;;
+ "-r") RAMTOP="$2" ; shift ;;
+ -?*) die "invalid option '$1'" ;;
+ *)
+ if [ "$INFILE" = "" ]; then
+ INFILE="$1"
+ elif [ "$OUTFILE" = "" ]; then
+ OUTFILE="$1"
+ else
+ die "extra junk on the command line: '$1'"
+ fi
+ ;;
+ esac
+ shift
+done
+
+type -p convert > /dev/null && type -p composite > /dev/null || \
+ die "Can't find 'convert' and 'composite' in \$PATH. Install ImageMagick?"
+
+[ "$INFILE" = "" ] && die "No input filename given"
+[ "$INFILE" = "-" ] && die "Reading stdin not supported"
+[ "$OUTFILE" = "" ] && die "No output filename given (use - for stdout)"
+
+# ASPECT pretends GR.8 pixels are square, GR.15 are 2x1 rectangles,
+# and GR.9 are 4x1. This isn't entirely true...
+case "$GRMODE" in
+ 8) W=320; H=192; COLORS=2; DEPTH=1; ASPECT=100; FGCOLOR=${FGCOLOR:-0x0c}; BGCOLOR=${BGCOLOR:-0x00} ;;
+ 15) W=160; H=192; COLORS=4; DEPTH=2; ASPECT=50 ;;
+ 9) W=80; H=192; COLORS=16; DEPTH=4; ASPECT=25 ;;
+ *) die "invalid graphics mode '$GRMODE' (only 8 and 15 supported)" ;;
+esac
+
+#[ "$NARROW" = "1" ] && W=$(( $W / 40 * 32 ))
+
+[ "$OUTFILE" = "" ] && OUTFILE="-"
+[ "$OUTFILE" != "-" ] && exec > $OUTFILE
+
+if [ "$LOADER" = "1" ]; then
+ if [ "$IMGSTART" != "" ]; then
+ die "-a option can't be combined with -x/-X"
+ fi
+
+ LOADEREND=$(( $LOADERADDR + 113 ))
+ IMGSTART=$(( $RAMTOP * 256 - 7856 ))
+
+ # xex header
+ printword 0xffff
+ printword $LOADERADDR
+ printword $LOADEREND
+
+ # data table (see loader.s)
+ printbyte $RAMTOP
+ printbyte $GRMODE
+ printbyte 0x04
+ printbyte ${FGCOLOR:-0x08}
+ printbyte ${BGCOLOR:-0x0c}
+ printbyte 0x00
+ printbyte 0x00
+ printbyte $SDMCTL
+
+ # code (see loader.s)
+ printbytes 78 a9 00 8d 0e d4 a9 60 85 d4 20 d4 00 ba ca bd 00 01
+ printbytes 38 e9 14 85 d4 bd 01 01 e9 00 85 d5 58 a9 40 8d
+ printbytes 0e d4 a0 00 b1 d4 85 6a a2 60 a9 0c 9d 42 03 20
+ printbytes 56 e4 a2 60 a9 0c 9d 4a 03 a0 01 b1 d4 9d 4b 03
+ printbytes a9 03 9d 42 03 a9 53 85 d6 a9 d6 9d 44 03 a9 00
+ printbytes 9d 45 03 20 56 e4 a0 02 b1 d4 99 c2 02 c8 c0 07
+ printbytes d0 f6 b1 d4 8d 2f 02 60
+
+ # INITAD segment
+ printbytes e2 02 e3 02
+ printword $(( LOADERADDR + 8 ))
+
+ # Narrow display needs 2nd DL LMS adjusted
+## if [ "$NARROW" = 1 ]; then
+## printword 0xffff
+## printword $(( IMGSTART - 182 ))
+## printword $(( IMGSTART - 181 ))
+## printword $(( IMGSTART + 32 * 94 ))
+## fi
+fi
+
+if [ "$IMGSTART" != "" ]; then
+ IMGBYTES=$(( $W * $H / 8 * $DEPTH ))
+ IMGEND=$(( $IMGSTART + $IMGBYTES - 1 ))
+ printword 0xffff
+ printword $IMGSTART
+ printword $IMGEND
+fi
+
+convert "$INFILE" $DITHER -scale ${ASPECT}%x100%\! -colorspace gray -scale ${W}x${H} -depth $DEPTH -colors $COLORS gif:- | \
+composite gif:- -size ${W}x${H} -depth $DEPTH -colors $COLORS -gravity center xc:black gray:-
+
+if [ "$VIEWER" = 1 ]; then
+ LOADEREND=$(( $LOADERADDR + 12 ))
+
+ # xex header
+ printword 0xffff
+ printword $LOADERADDR
+ printword $LOADEREND
+
+ # code (see viewer.s)
+ printbytes a9 ff 8d fc 02 ad fc 02 c9 ff f0 f9 60
+
+ # RUNAD segment
+ printbytes e0 02 e1 02
+ printword $LOADERADDR
+fi
+
+exit 0
+
+# dump pixels' RGB values as text:
+# convert in.png +dither -scale 320x192 -depth 2 -colors 4 -remap a8_ntsc_palette.png txt:- |sed 's,.*#\([0-9A-F]\{6\}\).*,\1,'|sort -u
+# could someday be used to support color images in GR.15, or something like APAC.