Actually, I hacked out a Poscscript program to draw 'subsec' genrated maps
some time ago. Here it is, no strings attached above James'.
These are to be considered as alterations to James' program
- ------------------------------------------------------------
psmapsub.c:
- ------------------------------------------------------------
/*
* mapsub - produce a subsector hex-grid map from subsector data
*
* SYNOPSIS
* mapsub <Subsector.dat >Subsector.hex
*
* DESCRIPTION
* Mapsub processes the star system information on the standard input and
* produces a hex-grid map on the standard output. The format expected is
* very precise, consisting of one formatted line for each system, each
* exactly 59 bytes followed by a newline. Example:
*
* "0102 Gruenwald B775400-9 N TN NI TI GP"
*
* XXYY System_Name_______ UPP______ B Trade_Codes___ Al Z GP
*
* Where:
* XXYY is the system coordinates, in the range 0101-3240
* System_Name is the 18-character system name
* UPP is the Universal Planetary profile
* B is the base code: 'N' navy, 'S' scout, 'A' both
* Trade_Codes is up to fifteen characters worth of Trading codes,
* from this list: TN (Terran-Norm), TP (Terran-Prime), AG
* (Agricultural), NA (Non-AG), IN (Industrial), NI (Non-IN), RI
* (Rich), PO (Poor), WA (Water world), DE (Desert World), VA
* (Vacuum World), AS (Asteroid Belt), IC (Ice-capped), CA (Subsector
* Capitol)
* The only Trade_Code that does anything is CA, which causes
* "Capitol" to be written into the system's hex.
* Al is the system alignment. "IM" is the official alignment for the
* Imperium. I use "IN" for independent worlds.
* Z is the travel zone, either " " (Green), "A" (Amber), "R" (Red).
* G is the gas-giant-present flag, either " " (None), or "G" (exists).
* P is the planetoids-present flag, either " " (None), or "P" (exists).
*
* The output is an array of empty and filled hexes, which look like this:
* ______
* / XXYY \ XXYY - System coordinates
* / * S \ * - Navy base, S - Starport class
* / ^ O . \ ^ - Scout base, "O" "@" or "%" - Desert or Non-desert
* \ System / world or Asteroid belt, . - Gas giant
* \ Name /
* \Zone__/ Zone - blank for green or circle for "amber" or
* filled circle for "RED"
*
* WARNING
* Mapsub assumes that the input is only one subsector's worth of worlds.
* if you give it a sector's worth of worlds (Example: "gensec | mapsub")
* it will print them all, overlapping many worlds!
*
* Ergo, if you want to generate worlds automatically, use gensec to
* produce a sector file of systems, then glean all the worlds belonging
* to a particular sector out of that file and put it in a subsector file,
* then use mapsub on the new subsector file.
*
* TO COMPILE
* On BSD systems, use: cc -O -s -o mapsub mapsub.c
* On SYSV systems, use: cc -O -DSYSV -s -o mapsub mapsub.c
*
* FILES
* Needs a blank hex map template, defined by default to be "./subhex".
* Change the MAP_TEMPLATE parameter to change this file's location.
*
* SEE ALSO
* gensec - the sector generator program (produces compatible format)
*
* AUTHOR
* James T. Perkins, [email removed], [email removed]
* Yngve Larsson, [email removed], ..!enea!liuida!yla
*
* BUGS
* The code is somewhat messy, as it was hacked out on a whim.
*
* As stated above, one cannot simply use the output of gensec as input
* to mapsub -- the gensec output must be edited.
*/
/*
Copyright 1987 James T. Perkins
PostScript additions by Yngve Larsson
This notice and any statement of authorship must be reproduced
on all copies. The author does not make any warranty expressed
or implied, or assumes any liability or responsiblity for the
use of this software.
Any distributor of copies of this software shall grant the
recipient permission for further redistribution as permitted
by this notice. Any distributor must distribute this software
without any fee or other monetary gains, unless expressed written
permission is granted by the author.
This software or its use shall not be: sold, rented, leased,
traded, or otherwise marketed without the expressed written
permission of the author.
If the software is modified in a manner creating derivative
copyrights, appropriate legends may be placed on derivative
work in addition to that set forth above.
Permission is hereby granted to copy, reproduce, redistribute or
otherwise use this software as long as the conditions above
are met.
All rights not granted by this notice are reserved.
*/
#define MAP_TEMPLATE "./subps" /* empty hex grid and PostScript file */
#include <stdio.h>
#include <strings.h>
char map[80]; /* in-memory copy of map that we operate on */
main(ac, av, envp)
int ac;
char *av[], *envp[];
{
char system[81], name[19], upp[10], trade[16], align[3];
char base, zone, gas, belt;
char *s;
int x, y, i;
FILE *fp;
/*
* Read hex map template into memory
*/
if ((fp = fopen(MAP_TEMPLATE, "r")) == NULL)
{
fprintf(stderr, "%s: cannot open %s.\n", av[0], MAP_TEMPLATE);
exit(1);
}
while (!feof(fp))
{
fgets(map, 80, fp);
printf("%s", map);
}
fclose(fp);
/*
* Start with empty, null-terminated strings
*/
bzero(name, sizeof(name));
bzero(upp, sizeof(upp));
bzero(trade, sizeof(trade));
bzero(align, sizeof(align));
/*
* Read in each system and place it on the map
*/
while (!feof(stdin))
{
fgets(system, sizeof(system), stdin);
sscanf(system,
"%2d%2d%*c%18c%*c%9c%*c%c%*c%15c%*c%2c%*c%c%*c%c%c\n",
&x, &y, name, upp, &base, trade, align,
&zone, &gas, &belt);
rem_trail_sp(name);
rem_trail_sp(trade);
/*
* write hex:
* ______
* / XXYY \
* / * S \
* / ^ @ . \
* \ System /
* \ Name /
* \______/
*/
printf("%2d %2d mapCoords \n", x, y);
switch (zone) {
case 'A':
printf("amberZone \n");
break;
case 'R':
printf("redZone \n");
break;
}
printf("(%.2d%.2d) hexNumber \n", x, y);
if (upp[1] == '0')
printf("asteroids \n");
else if (upp[3] == '0')
printf("desPlnt \n");
else
printf("liqPlnt \n");
if (upp[4] == '9' || upp[4] == 'A')
capitalize(name);
printf("(%s) name \n", name);
printf("(%c) starPort \n", upp[0]);
if (base == 'N' || base == 'A')
printf("navalBase \n");
if (base == 'S' || base == 'A')
printf("scoutBase \n");
if (gas == 'G')
printf("gasGiant \n");
printf("\n");
}
/*
* Write out finished map
*/
printf("showpage \n");
exit(0);
}
/*
* Remove all trailing spaces from the given null-terminated string
*/
rem_trail_sp(s)
char *s;
{
int i = strlen(s) - 1;
while (i >= 0 && s[i] == ' ')
{
s[i--] = '\0';
}
}
/*
* Convert lowercase characters to UPPERCASE
*/
capitalize(s)
char *s;
{
int i, k;
k = strlen(s);
for (i = 0 ; i != k ; i++)
if (s[i] >= 'a' && s[i] <= 'z')
s[i] = s[i] + 'A' - 'a';
}
- ----------------------------------------------------------
subps:
- ----------------------------------------------------------
%! PS-Adobe-1.0
% Traveller subsector map and mapping functions
%-----Constants-----
/cm { 72 mul 2.54 div } def % cm >> points
/unit { 1 cm mul } def
/topOfPageX 4.5 cm def
/topOfPageY 25 cm def
/nameFont /Times-Roman findfont 12 scalefont def
/portFont /Helvetica findfont 10 scalefont def
/numberFont /Helvetica findfont 8 scalefont def
%-----Basic Functions-----
/hex { % - >> -
gsave
-1 unit 0 rmoveto
currentpoint translate
60 rotate
5 {
1 unit 0 lineto
currentpoint translate
-60 rotate
} repeat
closepath
stroke
grestore
} def
/rowOfHex { % x y >> -
moveto
10 {
hex
0 0 3 sqrt unit sub rmoveto
} repeat
} def
/hexMap { % - >> -
/curX topOfPageX def
/curY topOfPageY def
4 {
curX curY rowOfHex
/curX curX 1.5 unit add def
/curY curY 3 sqrt 2 div unit sub def
curX curY rowOfHex
/curX curX 1.5 unit add def
/curY curY 3 sqrt 2 div unit add def
} repeat
} def
/mapCoords { % HexX HexY >> -
/actY exch 1 sub 10 mod 3 sqrt unit mul topOfPageY exch sub def
dup 2 mod 0 eq {
actY 3 sqrt 2 div unit sub def % displace column if HexX is even
} if
/actX exch 1 sub 8 mod 1.5 unit mul topOfPageX add def
} def
/getCoords { % - >> x y
actX actY
} def
/liqPlnt {
newpath
getCoords .1 unit 0 360 arc fill
} def
/desPlnt {
gsave
newpath
getCoords .1 unit 0 360 arc
gsave
1 setgray fill
grestore
.5 setlinewidth stroke
grestore
} def
/asteroids {
newpath
getCoords .1 unit add .04 unit 0 360 arc fill
getCoords exch .15 unit add exch .02 unit 0 360 arc fill
getCoords .15 unit sub exch .1 unit add exch .03 unit 0 360 arc fill
getCoords .04 unit sub exch .15 unit sub exch .05 unit 0 360 arc fill
getCoords .05 unit sub .02 unit 0 360 arc fill
} def
/name { % name >> -
getCoords moveto
nameFont setfont
dup stringwidth pop 2 div 0 exch sub
-.5 unit rmoveto
gsave
currentpoint translate
newpath
0 0 moveto
dup stringwidth exch pop 0 exch lineto
dup stringwidth lineto
dup stringwidth pop 0 lineto
closepath
1 setgray fill
grestore
show
} def
/starPort { % code >> -
getCoords moveto
portFont setfont
dup stringwidth pop 2 div 0 exch sub
.15 unit rmoveto
show
} def
/navalBase { % - >> -
gsave
getCoords moveto
-.5 unit .3 unit rmoveto
currentpoint translate
4 {
.2 unit 0 lineto
currentpoint translate
-144 rotate
} repeat
closepath
fill
grestore
} def
/scoutBase {
gsave
newpath
getCoords moveto
-.5 unit -.125 unit rmoveto
currentpoint translate
60 rotate
.15 unit 0 lineto
currentpoint translate
-120 rotate
.15 unit 0 lineto
closepath
fill
grestore
} def
/gasGiant {
gsave
newpath
getCoords moveto
.5 unit .3 unit rmoveto
currentpoint translate
0 0 .05 unit 0 360 arc fill
grestore
} def
/redZone {
newpath
.8 setgray
getCoords 2 3 div unit 0 360 arc fill
0 setgray
} def
/amberZone {
gsave
newpath
3 setlinewidth
.6 setgray
getCoords 2 3 div unit 0 360 arc stroke
grestore
} def
/hexNumber { % (XX YY) >> -
getCoords moveto
numberFont setfont
dup stringwidth pop 2 div 0 exch sub
.6 unit rmoveto
show
} def
%-----Main-----
hexMap
% Other system specs (start with zones)
- -----------------------------------------------------------
(Yes, the file is supposed to end like that. It will be appended by
the psmapsub routines.)
Notes:
You might want to fiddle with the constants "topOfPageX" and "topOfPageY"
if you have anything other than A4 paper size. These are the distances
to the highest leftmost hex on the map, counted from bottom and left
side of the page respectively. You can also change the constant "unit",
which is used as scaling factor throughout the program (except for fonts).
One important change is that James' maps had each even column of hexes
displaced upward. I believe GDW's maps displace these column downward, so
I changed this.
Enjoy (if it works.... :-)
Yngve Larsson
- -----------------------------------------------------------
Yngve Larsson UUCP: ...[email removed]
Dept of CIS Internet: [email removed]
Linkoping University, Sweden Phone: [phone removed]