aboutsummaryrefslogtreecommitdiff
path: root/convfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'convfont.c')
-rw-r--r--convfont.c265
1 files changed, 197 insertions, 68 deletions
diff --git a/convfont.c b/convfont.c
index a0ae0f4..1882efd 100644
--- a/convfont.c
+++ b/convfont.c
@@ -5,99 +5,188 @@
#include <unistd.h>
#include <stdio.h>
-/* usage:
- # extract the 1K atari ROM font:
+/* convfont - convert and combine the Atari ROM font and the
+ Apple II Taipan font for use with Atari Taipan.
+
+ Usage:
+
+ # Extract the 1K Atari ROM font:
dd if=atariosb.rom of=romfont bs=256 skip=8 count=4
- # extract the Apple II Taipan font:
+ # Extract the Apple II Taipan font:
dd if=taipan.dsk of=font bs=256 skip=54 count=3
- # create the Atari 8-bit Taipan font:
+ # Create the Atari 8-bit Taipan font as raw data:
cat romfont font | ./convfont > taifont.raw
- # or, create the Atari 8-bit Taipan font as a binary load:
+ # Or, create the Atari 8-bit Taipan font as a binary load,
+ # with load address set to FONT_ADDR. This has to be defined
+ # on the gcc command line when convfont is built (see Makefile):
+
cat romfont font | ./convfont -x > taifont.xex
+
+ In addition to writing the font on stdout, this program
+ also creates LORCHA.DAT and DAMAGED.DAT. If they already
+ exist, they are overwritten.
+
+ There is NO error checking in this program! It expects exactly
+ 1792 bytes on its stdin (as in the commands above).
*/
-/*
- taipan font file order:
- 0-31: `a-z{|}" block
- 32-63: @A-Z[\]^_
- 64-95: space !"#$%&'()*+,-./0-9:;>=<?
+/* Long-winded explanation of shipdata[] and how to edit it:
- atari screen code order:
- 0-31: space !"#$%&'()*+,-./0-9:;>=<?
- 32-63: @A-Z[\]^_
- 64-95 graphics chars
- 96-127: `a-z and 4 graphics chars
-*/
+ Custom characters for ship graphics. 1st byte
+ is screencode, the other 8 are the pixel data. The
+ screencodes aren't in any particular order. They
+ match the screencodes in shipshape[] and damaged_shipshape[].
+
+ This stuff was originally done with a perl script that
+ sliced up a PNG image of the lorcha, from an Apple II
+ emulator screenshot. The script is long gone (it's from
+ before I started using git for this project). At this
+ point, nobody should ever have to edit the graphics again.
+ I document the process I used, below, in case that turns
+ out to be incorrect.
+
+ Editing the ship graphics is a cumbersome mostly-manual
+ process. Basically you copy the pixel data (8 hex pairs, do
+ NOT copy the screencode too), and paste
+ it into the stdin of hex2block.pl. If you wanted to edit
+ the small flag on top of the right-hand sail:
+
+ 1. Locate its character code by looking at shipshape[]. It's
+ the rightmost character on the 2nd row, 0x53.
+ 2. Find the shipdata[] line that begins with 0x53.
+ 3. Copy *just* the pixel data (don't copy the 0x53).
+ 4. Run this:
+
+$ perl hex2block.pl > x.txt
+
+ 5. Paste your line of hex data in the terminal and press Enter.
+ x.txt ends up looking like e.g.:
+
+$ cat -A x.txt
+ $
+ $
+ X $
+ XXX $
+ XXXXX $
+ X XXX$
+ X $
+ X $
+
+ The $ are EOL markers put there by 'cat -A', so you can see
+ the trailing spaces. You can see the flag shape made of X's.
+
+ 6. Edit x.txt with your favorite text editor, using X and space
+ for lit/unlit pixels. There should be exactly 8 lines of 8
+ characters (each of which is an X or a space).
+
+ 7. Run this:
+
+$ perl block2hex.pl x.txt
+
+ ...which gives you hex data to paste into this file, e.g.:
+
+0x00, 0x00, 0x40, 0x70, 0x7c, 0x47, 0x40, 0x40
+
+ 8. Copy the hex data, and paste it back into this file, replacing
+ the original data for character 0x53.
+
+ As you can see, I *really* should have written an easier to use
+ tool for this. However, it might have taken me longer to do that
+ than it did to just grind through all the damaged-ship graphics.
+
+ Notes:
+
+ Screen codes 0x41, 0x43, 0x44, 0x45, 0x51, 0x52, 0x5a are box
+ drawing chars, used to draw the port status, firm naming, and
+ retirement screens. So don't try to use them as ship pieces!
+
+ 0x54 is the ^T ball character, copied from the Atari ROM font.
+ It looks OK as a hole made by a cannonball so I used it as-is
+ (or actually, used 0xd4, the inverse video version).
+
+ All the other graphics characters are used, plus a few printable
+ ones (square brackets, backslash, underscore).
+
+ When you're editing the ship graphics, uncomment the
+ #define LORCHA_TEST line near the top of taipan.c to see you
+ work in progress (wail on the space bar to repeatedly damage
+ the ships).
+
+ If you want ASCII art versions of the healthy and fully-damaged
+ lorcha, use "make lorcha.txt" and/or "make damaged.txt".
+ */
-/* custom characters for ship graphics. 1st byte
- is screencode, the other 8 are the pixel data. */
char shipdata[][9] = {
/* healthy ship blocks */
- {0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f},
- {0x03 , 0x18, 0x1f, 0x1f, 0x10, 0x10, 0x10, 0xff, 0xff},
- {0x04 , 0x00, 0xf0, 0xfc, 0x3e, 0x00, 0x00, 0xfc, 0xf0},
- {0x06 , 0x00, 0x00, 0x40, 0x70, 0x7c, 0x47, 0x40, 0x40},
- {0x1b , 0x1f, 0x3f, 0xff, 0x3f, 0x1f, 0x3f, 0xff, 0x7f},
- {0x1c , 0xc0, 0xf0, 0xfc, 0xf0, 0xc0, 0xf0, 0xfc, 0xf0},
- {0x1d , 0x07, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x07, 0x0f},
- {0x1e , 0xfe, 0xfc, 0xfe, 0xff, 0xfe, 0xf8, 0xfe, 0xff},
- {0x20 , 0xfe, 0xf8, 0xfe, 0xff, 0xfe, 0xfe, 0xfd, 0xf9},
- {0x3b , 0xc0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f},
- {0x3c , 0x00, 0x00, 0xc0, 0xff, 0x8f, 0x8e, 0x8e, 0xfe},
- {0x3d , 0x38, 0x38, 0x38, 0x38, 0xff, 0x38, 0x38, 0x38},
- {0x3e , 0x00, 0x00, 0x00, 0x01, 0xff, 0xe3, 0xe3, 0xe3},
- {0x3f , 0x00, 0x00, 0x00, 0xff, 0x8e, 0x8e, 0x8e, 0xff},
- {0x40 , 0xc3, 0xcf, 0xff, 0xff, 0x3f, 0x3e, 0x3c, 0xf8},
- {0x46 , 0x1f, 0x0f, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03},
- {0x47 , 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80},
-
- /*
-A, 50, 00 00 00 00 00 00 47 3e
-B, 5b, 18 1f 1d 10 10 10 fb fd
-E, 5e, 1f 0f 1f 3f 1f 3b ff 7f
-G, 5f, 00 01 03 07 03 03 07 06
-H, 60, f0 f8 fb fe fe f8 fe 7f
-I, 7b, fe f8 be 97 8e be fc f8
-J, 7d, 00 00 03 1d 1f 37 3b 1f
-K, 7e, 00 00 00 00 80 c1 e3 e3
-O, 7f, c0 c0 f0 e0 20 32 3c f1
-*/
+ {0x42 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f}, // ^B
+ {0x4e , 0x18, 0x1f, 0x1f, 0x10, 0x10, 0x10, 0xff, 0xff}, // ^N
+ {0x4f , 0x00, 0xf0, 0xfc, 0x3e, 0x00, 0x00, 0xfc, 0xf0}, // ^O
+ {0x53 , 0x00, 0x00, 0x40, 0x70, 0x7c, 0x47, 0x40, 0x40}, // ^S
+ {0x55 , 0x1f, 0x3f, 0xff, 0x3f, 0x1f, 0x3f, 0xff, 0x7f}, // ^U
+ {0x56 , 0xc0, 0xf0, 0xfc, 0xf0, 0xc0, 0xf0, 0xfc, 0xf0}, // ^V
+ {0x57 , 0x07, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x07, 0x0f}, // ^W
+ {0x58 , 0xfe, 0xfc, 0xfe, 0xff, 0xfe, 0xf8, 0xfe, 0xff}, // ^X
+ {0x5b , 0xfe, 0xf8, 0xfe, 0xff, 0xfe, 0xfe, 0xfd, 0xf9}, // Esc symbol
+ {0x3b , 0xc0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f}, // [
+ {0x3c , 0x00, 0x00, 0xc0, 0xff, 0x8f, 0x8e, 0x8e, 0xfe}, // backslash
+ {0x3d , 0x38, 0x38, 0x38, 0x38, 0xff, 0x38, 0x38, 0x38}, // ]
+ {0x5c , 0x00, 0x00, 0x00, 0x01, 0xff, 0xe3, 0xe3, 0xe3}, // up arrow
+ {0x3f , 0x00, 0x00, 0x00, 0xff, 0x8e, 0x8e, 0x8e, 0xff}, // _
+ {0x40 , 0xc3, 0xcf, 0xff, 0xff, 0x3f, 0x3e, 0x3c, 0xf8}, // heart (null)
+ {0x46 , 0x1f, 0x0f, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03}, // ^F
+ {0x47 , 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80}, // ^G
+
/* damaged ship blocks */
- { 0x50 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x3e},
- { 0x5b , 0x18, 0x1f, 0x1d, 0x10, 0x10, 0x10, 0xfb, 0xfd},
- { 0x5e , 0x1f, 0x0f, 0x1f, 0x3f, 0x1f, 0x3b, 0xff, 0x7f},
- { 0x5f , 0x00, 0x01, 0x03, 0x07, 0x03, 0x03, 0x07, 0x06},
- { 0x60 , 0xf0, 0xf8, 0xfb, 0xfe, 0xfe, 0xf8, 0xfe, 0x7f},
- { 0x7b , 0xfe, 0xf8, 0xbe, 0x97, 0x8e, 0xbe, 0xfc, 0xf8},
- { 0x7d , 0x00, 0x00, 0x03, 0x1d, 0x1f, 0x37, 0x3b, 0x1f},
- { 0x7e , 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0xe3, 0xe3},
- { 0x7f , 0xc0, 0xc0, 0xf0, 0xe0, 0x20, 0x32, 0x3c, 0xf1},
+ { 0x50 , 0x00, 0x00, 0x00, 0x00, 0x83, 0xc3, 0xe3, 0xe3}, // ^P
+ { 0x5d , 0xff, 0x9f, 0x8f, 0x9f, 0xf9, 0xf8, 0xf9, 0xff}, // down arrow
+ { 0x48 , 0x1f, 0x3b, 0xfd, 0x39, 0x18, 0x31, 0xfb, 0x7f}, // ^H
+ { 0x49 , 0xff, 0xff, 0xfd, 0xe1, 0x83, 0x0f, 0xff, 0xff}, // ^G
+ { 0x4a , 0xd5, 0xa3, 0x41, 0x81, 0x40, 0xb0, 0xfc, 0xff}, // ^I
+ { 0x4b , 0xc0, 0xf0, 0xfc, 0xf0, 0xc0, 0x00, 0x80, 0xf0}, // ^J
+ { 0x5e , 0x1f, 0x39, 0xf1, 0x39, 0x1f, 0x3c, 0xf8, 0x7c}, // L arrow
+ { 0x5f , 0xfe, 0xf8, 0xee, 0xcf, 0x9e, 0xbe, 0xfd, 0xf9}, // R arrow
+ { 0x60 , 0xfe, 0xbc, 0xc6, 0xcf, 0x96, 0xd8, 0xfe, 0xff}, // diamond
+ { 0x4c , 0xff, 0xff, 0xff, 0xff, 0xe8, 0x81, 0xe1, 0xff}, // ^L (UL 1/4 blk)
+ { 0x4d , 0xff, 0x8f, 0x8f, 0xe7, 0xfe, 0xf8, 0xf0, 0xff}, // ^M
+ { 0x7b , 0xfe, 0xf8, 0xbe, 0x97, 0x8e, 0xbe, 0xfc, 0xf8}, // spades
+ { 0x7d , 0xc0, 0xfe, 0xeb, 0xc7, 0xc3, 0xe7, 0x7f, 0x1f}, // clrscr (bent arrow)
+ { 0x7e , 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0xe3, 0xe3}, // left triangle
+ { 0x7f , 0xc3, 0xce, 0xf8, 0xf0, 0x30, 0x30, 0x3c, 0xfe}, // right triangle
/* end of ship data marker */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
-/* this ends up in LORCHA.DAT */
+/* This ends up in LORCHA.DAT, verbatim. See shipshape[] above
+ for the definitions of each screencode used here. If you can't
+ find a screencode in shipshape[], it's using the regular font
+ character (e.g. 0x00 is a space, 0x80 is an inverse space
+ aka solid 8x8 block). */
char shipshape[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x03, 0x04, 0x00, 0x06,
- 0x00, 0x00, 0x1b, 0x80, 0x1c, 0x1d, 0x1e,
- 0x00, 0x00, 0x1b, 0x80, 0x1c, 0x1d, 0x20,
- 0x00, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
+ 0x00, 0x00, 0x42, 0x4e, 0x4f, 0x00, 0x53,
+ 0x00, 0x00, 0x55, 0x80, 0x56, 0x57, 0x58,
+ 0x00, 0x00, 0x55, 0x80, 0x56, 0x57, 0x5b,
+ 0x00, 0x3b, 0x3c, 0x3d, 0x5c, 0x3f, 0x40,
0x00, 0x46, 0x80, 0x80, 0x80, 0x80, 0x47,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+/* DAMAGED.DAT - each time a lorcha gets damaged, a random
+ character from here overwrites the original shipshape[]
+ character in screen RAM. See draw_lorcha.s for details.
+ If a part of the ship can't display damage, it'll have
+ the same screencode here as it does in shipshape[]. */
char damaged_shipshape[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x50, 0x5b, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x5e, 0xd4, 0x00, 0x5f, 0x1e,
- 0x00, 0x00, 0x5e, 0xd4, 0x00, 0x5f, 0x60,
- 0x00, 0x7d, 0x7e, 0x7c, 0x7e, 0x7e, 0x7f,
- 0x00, 0x46, 0xcc, 0x87, 0xcc, 0x8e, 0x47,
+ 0x00, 0x00, 0x42, 0x4e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5e, 0x4a, 0x56, 0x57, 0x60,
+ 0x00, 0x00, 0x48, 0xd4, 0x4b, 0x57, 0x5f,
+ 0x00, 0x7d, 0x7e, 0x7c, 0x7e, 0x50, 0x7f,
+ 0x00, 0x46, 0x4c, 0x5d, 0x4d, 0x49, 0x47,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
@@ -125,19 +214,52 @@ void clear0bits(unsigned char *b, int lim) {
} while(--lim > 0);
}
+/*
+ taipan font file order:
+ 0-31: `a-z{|}" block
+ 32-63: @A-Z[\]^_
+ 64-95: space !"#$%&'()*+,-./0-9:;>=<?
+
+ atari screen code order:
+ 0-31: space !"#$%&'()*+,-./0-9:;>=<?
+ 32-63: @A-Z[\]^_
+ 64-95 graphics chars
+ 96-127: `a-z and 4 graphics chars
+*/
+
int main(int argc, char **argv) {
int i, j;
unsigned char font[1024], xex[6];
+ /* The first 1024 bytes of stdin are the Atari ROM font,
+ taken from an image of the ROM OS. */
read(0, font, 1024);
+
+ /* The remaining 768 bytes are the Taipan Apple II font,
+ extracted from the .dsk image. Its characters are in a
+ different order than the Atari expects them, so use 3 reads
+ with appropriate offsets/lengths. The Apple also packs the
+ pixels into each byte backwards from what the Atari expects,
+ so bitswap() fixes that. */
read(0, font + (96 * 8), 32 * 8);
bitswap(font + (96 * 8), 32 * 8);
+
read(0, font + (32 * 8), 32 * 8);
bitswap(font + (32 * 8), 32 * 8);
+
read(0, font + (0 * 8), 32 * 8);
bitswap(font + (0 * 8), 32 * 8);
- /* this stuff is from visual inspection via bitmapdump.pl */
+ /* This stuff is from visual inspection via bitmapdump.pl.
+ The Apple uses 7-bit-wide fonts. The high bit isn't displayed,
+ and the Apple font has it set on some of the characters. Not
+ sure if it has a meaning on the Apple, but it shows up as a
+ vertical bar at the right edge of the character here. Since we already
+ bit-swapped the font data, clear the 0 bit on the characters
+ where it's needed.
+ */
+ clear0bits(font + 0x018, 8);
+ clear0bits(font + 0x030, 8);
clear0bits(font + 0x1f8, 7);
clear0bits(font + 0x301, 7);
clear0bits(font + 0x308, 8);
@@ -148,7 +270,8 @@ int main(int argc, char **argv) {
clear0bits(font + 0x040, 16);
clear0bits(font + 0x1e8, 8);
- /* fix the vertical bar */
+ /* Fix the vertical bar (put it back to Atari ROM spec), since
+ we're using it as a box-drawing character. */
font[0x3e0] =
font[0x3e1] =
font[0x3e2] =
@@ -165,14 +288,20 @@ int main(int argc, char **argv) {
}
}
+ /* if we got an argument, assume it's -x, and write the .xex
+ header before the font data. */
if(argc > 1) {
xex[0] = xex[1] = 0xff;
xex[2] = FONT_ADDR % 256; xex[3] = FONT_ADDR / 256; /* load address $2000 */
xex[4] = 0xff; xex[5] = 0x23; /* end address $23ff */
write(1, xex, 6);
}
+
+ /* write the 1K font to stdout. */
write(1, font, 1024);
+ /* create LORCHA.DAT and DAMAGED.DAT, which get incbin'ed by
+ draw_lorcha.s. NO error checking here! */
i = open("LORCHA.DAT", O_WRONLY | O_CREAT, 0666);
write(i, shipshape, sizeof(shipshape));
close(i);