home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
science
/
starchrt
/
patch
/
starst.c
< prev
Wrap
Text File
|
1989-03-23
|
18KB
|
510 lines
/*
** Atari ST driver for starchart.
** Works on color systems only, compiled with Mark Williams C.
** Written by Dave Yearke (dgy@sigmast), September 1988.
** Portions of this program (c) Mark Williams Company.
** Thanks to the authors of the other starchart drivers for giving
** me some examples to work from.
*/
extern int exit_and_save;
extern char *getenv(), picturefile[];
#include <ctype.h> /* isprint(), iscntrl(), etc. */
#include <linea.h> /* Line A (low-level graphics) routines. */
#include <osbind.h> /* Operating system bindings */
#include <vdibind.h> /* The virtual device interface routines */
#include <xbios.h> /* Extended BIOS bindings */
#include "starchrt.h" /* Starchart information */
/* Global line A variables used by vdi; MUST be included */
int contrl[12], intin[128], ptsin[128], intout[128], ptsout[128];
/* Array used by vs_clip() */
int cliparray[] = { 1, 1, 319, 199 };
/* Arrays used by v_opvwk() */
int work_in[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
int work_out[57];
#define TRUE 1
#define NULL 0
/*
** Starchart was designed for 1024x768 pixels. These macros scale the
** image to the 320x200 Atari ST low-resolution (16-color) mode. Also,
** the y coord is subtracted from 200 so the image isn't upside-down.
*/
#define xadjust(x) ((x) * 0.3125)
#define yadjust(y) (200 - ((y) * 0.2604167))
struct la_font *fontp; /* Line A font header. */
char line[100], linemode, *p;
char scr_wrk[1024];
int vdihandle; /* Virtual device's handle */
int CURRX, CURRY, currez, old_color[16], oldrez = 99; /* 99 is impossible! */
/*
** Settings for the palette, given as RGB, 3 bits for each color (512 total).
** I tried to use different registers for different types of objects so they
** could be set individually (for example, in DEGAS you could blink a register
** for an object you're trying to point out).
*/
int new_color[16] = { 0x000, /* Black - Background color */
0x777, /* White - 1st and higher mag. stars */
0x666, /* White - 2nd mag. stars */
0x555, /* White - 3rd mag. stars */
0x444, /* White - 4th mag. stars */
0x333, /* White - 5th mag. stars */
0x222, /* White - 6th and lower mag. stars */
0x222, /* White - Nebulae, Galaxies, Clusters */
0x007, /* Blue - 1st and higher mag. stars */
0x700, /* Red - 1st and higher mag. stars */
0x770, /* Yellow - Sol */
0x704, /* Pink - Inferior Planets */
0x404, /* Purple - Superior Planets */
0x020, /* Dark Green - Dotted lines */
0x200, /* Dark Red - Hyphenated lines */
0x003 }; /* Deep Blue - Text and borders */
/*
** These are reverse-image colors for the background and stars, used when the
** 'r' key is hit when the program pauses before exiting. Switching these
** registers makes a .ice output image for a screen dump to a printer.
*/
int rev_color[8] = { 0x777, /* White - Background color */
0x000, /* Black - 1st and higher mag. stars */
0x222, /* Black - 2nd mag. stars */
0x333, /* Black - 3rd mag. stars */
0x444, /* Black - 4th mag. stars */
0x555, /* Black - 5th mag. starag. starag. starag. starag. star /* Loop if 'r' is pressed, return for anything else */
switch (i = Crawcin()) { /* Wait for keypress before quitting */
case 'r': /* Reverse the color registers */
if (Setcolor(0, -1) == 0) { /* If normal, reverse it */
for (i = 0; i < 8; i++)
Setcolor(i, rev_color[i]);
} else { /* Make it normal */
for (i = 0; i < 8; i++)
Setcolor(i, new_color[i]);
}
continue; /* Restart the loop */
break;
case 's': /* Save as a DEGAS picture */
strcpy(picturefile, "star.pi1");
savepic();
break;
case 'S': /* Save as a NeoChrome picture */
strcpy(picturefile, "star.neo");
savepic();
break;
default:
break;
}
break;
}
vecreset();
}
/*
** Restore the screen
*/
vecreset()
{
int i;
v_clsvwk(vdihandle); /* Close the virtual workscreen */
appl_exit(); /* Remove the application from AES */
Cconws("\033H\033J"); /* Clear the screen */
Setscreen((char *)-1, (char *)-1, oldrez); /* Set resolution */
for (i = 0; i < 16; i++) /* Set the colors back to their saved values */
Setcolor(i, old_color[i]);
if (((getenv("PATH")) == 0) || (strlen(getenv("PATH")) == 0))
linea9(); /* Show mouse pointer */
else /* If called from a shell */
Cursconf(1, 0); /* Show cursor */
}
/*
** Save the screen as a DEGAS or NeoChrome picture
*/
savepic()
{
int neo = 0, file; /* Assume DEGAS file */
if (strrchr(picturefile, '.') != NULL) { /* Extender given */
if ((!strncmp(picturefile + strrchr(picturefile, '.'), ".neo", 4)) ||
(!strncmp(picturefile + strrchr(picturefile, '.'), ".NEO", 4)))
++neo; /* Save as a NeoChrome picture */
} else
strcat(picturefile, ".pi1");
if ((file = creat(picturefile, 0)) == -1)
die("Cannot open %s.", picturefile);
if (neo) /* NeoChrome has two extra null bytes at the beginning */
if (write(file, &currez, 2) != 2)
die("Write failure on file %s.", picturefile);
if (write(file, &currez, 2) != 2) /* Write the resolution */
die("Write failure on file %s.", picturefile);
if (write(file, &new_color[0], 32) != 32) /* Write the palette info */
die("Write failure on file %s.", picturefile);
if (neo) /* NeoChrome has a 128-byte header, so we'll pad with 94 bytes */
for (neo = 0; neo < 47; ++neo) /* Recycle the variable "neo" */
if (write(file, &currez, 2) != 2)
die("Write failure on file %s.", picturefile);
if (write(file, Physbase(), 32000) != 32000) /* Write the screen */
die("Write failure on file %s.", picturefile);
close(file); /* Done! (that wasn't too bad, was it?) */
}
/*
** This function is duplicated in starchrt.c for non-ST versions, using
** the INTERACTIVE manifest constant.
*/
die(a,b)
char *a, *b;
{
char buf[80];
int i;
if (oldrez != 99) /* See if we ever initialized the screen. */
vecreset(); /* Reset the screen to something sane */
if (!strncmp(b, "\nusage", 6)) { /* Sub in the ST's usage */
Cconws("\n\rusage:\tstar* [ Ra Dcl Scale Title Maglim Labellim ]\n");
Cconws("\ror\tstar* [ -r Ra -d Dcl -s Scale -t Title -m Maglim -l ");
Cconws("Labellim -f x.str ]\n\ror\tstar* [ -c con (3 or 4 letters ");
Cconws("chosen from con.loc) -l ... ]\n\ror\tstarst -x [ file.PI1 ");
Cconws("| file.NEO ] ... (to exit and save screen)\n\n\r");
Cconws("Portions of this program, copyright 1984, ");
Cconws("Mark Williams Company");
} else {
sprintf(buf, a, b);
Cconws(buf);
}
Cconws("\n\r"); /* Cconws does not map \n into \n\r */
/* We want to hold the screen if invoked from the GEM desktop;
the desktop doesn't usually set any environment variables,
and if getenv() does find anything, it's probably a NULL string. */
if (((getenv("PATH")) == 0) || (strlen(getenv("PATH")) == 0)) {
Cconws("press any key to continue: "); /* Hold screen if desktop */
i = Crawcin(); /* Read raw character input */
}
exit(1);
}
/*
** Functions for manipulating text.
*/
/*
** This function sets the point size for text. (not applicable)
*/
vecsize (points)
int points;
{
}
/*
** This function puts text on the screen.
*/
vecsyms (x, y, s)
int x,y;
char *s;
{
register char *ptr;
register unsigned int tmp;
if (*s == '\0') /* Don't bother if the string is empty */
return; /* (A null char can make linea8() crash!) */
fontp = la_init.li_a1[0]; /* 6x6 system font */
FBASE = fontp->font_data; /* Pointer to start of font form */
FWIDTH = fontp->font_width; /* Width of font form */
DELY = fontp->font_height; /* Height of character in font */
DSTX = xadjust(x);
if ((DSTY = yadjust(y)) > 2)
DSTY -= 2; /* This vertically centers the text on the line */
if (DSTY > 191)
DSTY = 191; /* Make sure the bottom line shows up */
ptr = s;
do { /* Output the characters until the end of the string is hit */
if (!iscntrl(*ptr)) {
tmp = *ptr - fontp->font_low_ade; /* Find the character data */
SRCX = fontp->font_char_off[tmp]; /* within the font data */
DELX = fontp->font_char_off[tmp + 1] - SRCX;
/* Check screen boundaries */
if ((DSTX > 0) && (DSTX < 311) && (DSTY > 0))
if (isspace(*ptr)) {
WMODE = 1; /* Writing mode = transparent */
linea8();
WMODE = 0; /* Writing mode = replace */
} else
linea8(); /* Line A trap for text blit routine */
}
} while (*++ptr != '\0');
}
/*
** This function puts text on the screen using the greek alphabet.
** (Well, not yet, but someday ... :-))
*/
vecsymsgk(s, x, y)
char *s;
{
vecsyms(s, x, y);
}
/*
** Functions for drawing points and lines.
*/
/*
** Change the current position of x and y.
*/
vecmove (x, y)
int x,y;
{
CURRX = x;
CURRY = y;
}
/*
** Move to a new location (x1, y1) and draw a solid line to (x2, y2).
*/
vecmovedraw (x1, y1, x2, y2)
int x1, y1, x2, y2;
{
vecmove(x1, y1);
vecdraw(x2, y2);
}
/*
** Draw a solid line to (x,y)
*/
vecdraw (x, y)
int x,y;
{
if (linemode != 'S') {
linemode = 'S';
COLBIT0 = 1; /* Set the bit plane for line drawing (color 15) */
COLBIT1 = 1;
COLBIT2 = 1;
COLBIT3 = 1;
}
X1 = xadjust(CURRX);
Y1 = yadjust(CURRY);
X2 = xadjust(CURRX = x);
Y2 = yadjust(CURRY = y);
linea3(); /* Line blit routine */
}
/*
** Draw a dotted line (dark green on the ST) to (x,y)
*/
vecdrawdot(x, y)
{
if (linemode != 'D') {
linemode = 'D';
COLBIT0 = 1; /* Set the bit plane for line drawing (color 13) */
COLBIT1 = 0;
COLBIT2 = 1;
COLBIT3 = 1;
}
X1 = xadjust(CURRX);
Y1 = yadjust(CURRY);
X2 = xadjust(CURRX = x);
Y2 = yadjust(CURRY = y);
linea3();
}
/*
** Draw a hyphenated line (dark red on the ST) to (x,y)
*/
vecdrawhyph(x, y)
{
if (linemode != 'H') {
linemode = 'H';
COLBIT0 = 0; /* Set the bit plane for line drawing (color 14) */
COLBIT1 = 1;
COLBIT2 = 1;
COLBIT3 = 1;
}
X1 = xadjust(CURRX);
Y1 = yadjust(CURRY);
X2 = xadjust(CURRX = x);
Y2 = yadjust(CURRY = y);
linea3();
}
/*
** Draw a horizontal line.
*/
drawlen (x, y, dx, dy, len)
int x, y, dx, dy, len;
{
if (linemode != 'S') {
linemode = 'S';
COLBIT0 = 1; /* Set the bit plane for line drawing (color 15) */
COLBIT1 = 1;
COLBIT2 = 1;
COLBIT3 = 1;
}
X1 = xadjust(x + dx);
Y1 = yadjust(y + dy);
X2 = xadjust(CURRX = x + dx + len - 1);
Y2 = yadjust(CURRY = y + dy);
linea3();
}
/*
** Functions for astronomical objects.
*/
/*
** Draw the sun or a planet
*/
drawPlan(x, y, mag, type, color)
int x, y, mag, type;
char *color;
{
if (type == 'S')
INTIN[0] = 10; /* Yellow for the Sun */
else if ((type == 'M') || (type == 'V'))
INTIN[0] = 11; /* Pink for inferior planets (Mercury or Venus) */
else
INTIN[0] = 12; /* Purple for superior planets (m, J, s, U, or N) */
PTSIN[0] = xadjust(CURRX = x);
PTSIN[1] = yadjust(CURRY = y);
if (linea2() == 0) /* See if there's anything there already */
linea1(); /* Put a pixel on the screen */
}
/*
** Draw a star.
*/
drawStar(x, y, mag, type, color)
int x, y, mag, type;
char *color;
{
if (mag > 6)
INTIN[0] = 6;
else if (mag < 1)
INTIN[0] = 1;
else
INTIN[0] = mag; /* No conversion necessary, direct map into palette */
if (mag < 2) /* Brightest stars will be in color if possible */
if (color != NULL)
if ((color[0] == 'O') || (color[0] == 'B'))
INTIN[0] = 8; /* Color register 8 holds blue */
else if ((color[0] == 'K') || (color[0] == 'M'))
INTIN[0] = 9; /* Color register 9 holds red */
PTSIN[0] = xadjust(CURRX = x);
PTSIN[1] = yadjust(CURRY = y);
if (mag < 1)
drawBigStar(x, y); /* Bright stars clobber anything under them */
else if (linea2() == 0) /* See if there's anything there already */
linea1();
}
/*
** Draw a bright star as a cross shape.
*/
drawBigStar(x, y)
int x, y;
{
linea1(); /* x, y */
--PTSIN[0];
linea1(); /* x-1, y */
++PTSIN[0];
--PTSIN[1];
linea1(); /* x, y-1 */
PTSIN[1] += 2;
linea1(); /* x, y+1 */
++PTSIN[0];
--PTSIN[1];
linea1(); /* x+1, y */
}
/*
** Draw a nebula. ('type' = 'D' for diffuse, 'P' for planetary)
*/
drawNebu(x, y, mag, type, color)
int x, y, mag, type;
char *color;
{
/* This isn't as clever as cstar() in starimag.c, but it's fast */
INTIN[0] = 7; /* Make 'em faint, with this shape: */
PTSIN[0] = xadjust(CURRX = x) - 1; /* ** */
PTSIN[1] = yadjust(CURRY = y); /* * * */
linea1(); /* x-1, y ** */
++PTSIN[1];
linea1(); /* x-1, y+1 */
++PTSIN[0];
++PTSIN[1];
linea1(); /* x, y+2 */
PTSIN[1] -= 3;
linea1(); /* x, y-1 */
++PTSIN[0];
++PTSIN[1];
linea1(); /* x+1, y */
++PTSIN[1];
linea1(); /* x+1, y+1 */
}
/*
** Draw a galaxy. ('type' = 'P' for sphere, 'S' for spiral)
*/
drawGalx(x, y, mag, type, color)
int x, y, mag, type;
char *color;
{
int i;
CURRX = x;
CURRY = y;
INTIN[0] = 7; /* Make 'em faint, with this shape: */
PTSIN[0] = xadjust(CURRX = x) - 2; /* ** * */
PTSIN[1] = yadjust(CURRY = y); /* ****** */
for (i = 0; i < 6; ++i) { /* * ** */
PTSIN[0] += 1;
linea1(); /* (x-2)+i, y */
}
++PTSIN[0];
--PTSIN[1];
linea1(); /* x+4, y-1 */
PTSIN[0] -= 3;
linea1(); /* x+1, y-1 */
--PTSIN[0];
linea1(); /* x, y-1 */
PTSIN[1] += 2;
linea1(); /* x, y+1 */
++PTSIN[0];
linea1(); /* x+1, y+1 */
PTSIN[0] -= 4;
linea1(); /* x-3, y+1 */
}
/*
** Draw a cluster. ('type' = 'G' for glob., 'O' for open, 'C' for Galactic)
*/
drawClus(x, y, mag, type, color)
int x, y, mag, type;
char *color;
{
INTIN[0] = 7; /* Make 'em faint, with this shape: */
PTSIN[0] = xadjust(CURRX = x); /* * * */
PTSIN[1] = yadjust(CURRY = y); /* * * * */
linea1(); /* x, y * * */
PTSIN[0] -= 2;
linea1(); /* x-2, y */
++PTSIN[0];
--PTSIN[1];
linea1(); /* x-1, y-1 */
PTSIN[0] += 2;
linea1(); /* x+1, y-1 */
PTSIN[1] += 2;
linea1(); /* x+1, y+1 */
PTSIN[0] -= 2;
linea1(); /* x-1, y+1 */
PTSIN[0] += 3;
--PTSIN[1];
linea1(); /* x+2, y */
}