home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / apps / science / starchrt / patch / starst.c < prev   
Text File  |  1989-03-23  |  18KB  |  510 lines

  1. /*
  2. ** Atari ST driver for starchart.
  3. ** Works on color systems only, compiled with Mark Williams C.
  4. ** Written by Dave Yearke (dgy@sigmast), September 1988.
  5. ** Portions of this program (c) Mark Williams Company.
  6. ** Thanks to the authors of the other starchart drivers for giving
  7. ** me some examples to work from.
  8. */
  9.  
  10. extern int exit_and_save;
  11. extern char *getenv(), picturefile[];
  12.  
  13. #include <ctype.h>    /* isprint(), iscntrl(), etc. */
  14. #include <linea.h>    /* Line A (low-level graphics) routines. */
  15. #include <osbind.h>   /* Operating system bindings */
  16. #include <vdibind.h>  /* The virtual device interface routines */
  17. #include <xbios.h>    /* Extended BIOS bindings */
  18. #include "starchrt.h" /* Starchart information */
  19.  
  20. /* Global line A variables used by vdi; MUST be included */
  21. int contrl[12], intin[128], ptsin[128], intout[128], ptsout[128];
  22. /* Array used by vs_clip() */
  23. int cliparray[] = { 1, 1, 319, 199 };
  24. /* Arrays used by v_opvwk() */
  25. int work_in[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
  26. int work_out[57];
  27.  
  28. #define TRUE 1
  29. #define NULL 0
  30.  
  31. /*
  32. ** Starchart was designed for 1024x768 pixels.  These macros scale the
  33. ** image to the 320x200 Atari ST low-resolution (16-color) mode.  Also,
  34. ** the y coord is subtracted from 200 so the image isn't upside-down.
  35. */
  36. #define xadjust(x) ((x) * 0.3125)
  37. #define yadjust(y) (200 - ((y) * 0.2604167))
  38.  
  39. struct la_font *fontp; /* Line A font header. */
  40. char line[100], linemode, *p;
  41. char scr_wrk[1024];
  42. int vdihandle; /* Virtual device's handle */
  43.  
  44. int CURRX, CURRY, currez, old_color[16], oldrez = 99; /* 99 is impossible! */
  45.  
  46. /*
  47. ** Settings for the palette, given as RGB, 3 bits for each color (512 total).
  48. ** I tried to use different registers for different types of objects so they
  49. ** could be set individually (for example, in DEGAS you could blink a register
  50. ** for an object you're trying to point out).
  51. */
  52. int new_color[16] = { 0x000,   /* Black      - Background color */
  53.                       0x777,   /* White      - 1st and higher mag. stars */
  54.                       0x666,   /* White      - 2nd mag. stars */
  55.                       0x555,   /* White      - 3rd mag. stars */
  56.                       0x444,   /* White      - 4th mag. stars */
  57.                       0x333,   /* White      - 5th mag. stars */
  58.                       0x222,   /* White      - 6th and lower mag. stars */
  59.                       0x222,   /* White      - Nebulae, Galaxies, Clusters */
  60.                       0x007,   /* Blue       - 1st and higher mag. stars */
  61.                       0x700,   /* Red        - 1st and higher mag. stars */
  62.                       0x770,   /* Yellow     - Sol */
  63.                       0x704,   /* Pink       - Inferior Planets */
  64.                       0x404,   /* Purple     - Superior Planets */
  65.                       0x020,   /* Dark Green - Dotted lines */
  66.                       0x200,   /* Dark Red   - Hyphenated lines */
  67.                       0x003 }; /* Deep Blue  - Text and borders */
  68.  
  69. /*
  70. ** These are reverse-image colors for the background and stars, used when the
  71. ** 'r' key is hit when the program pauses before exiting.  Switching these
  72. ** registers makes a .ice output image for a screen dump to a printer.
  73. */
  74. int rev_color[8]  = { 0x777,   /* White      - Background color */
  75.                       0x000,   /* Black      - 1st and higher mag. stars */
  76.                       0x222,   /* Black      - 2nd mag. stars */
  77.                       0x333,   /* Black      - 3rd mag. stars */
  78.                       0x444,   /* Black      - 4th mag. stars */
  79.                       0x555,   /* Black      - 5th mag. starag. starag. starag. starag. star /* Loop if 'r' is pressed, return for anything else */
  80.                switch (i = Crawcin()) { /* Wait for keypress before quitting */
  81.                case 'r': /* Reverse the color registers */
  82.                     if (Setcolor(0, -1) == 0) { /* If normal, reverse it */
  83.                          for (i = 0; i < 8; i++)
  84.                               Setcolor(i, rev_color[i]);
  85.                     } else { /* Make it normal */
  86.                          for (i = 0; i < 8; i++)
  87.                               Setcolor(i, new_color[i]);
  88.                     }
  89.                     continue; /* Restart the loop */
  90.                     break;
  91.                case 's': /* Save as a DEGAS picture */
  92.                     strcpy(picturefile, "star.pi1");
  93.                     savepic();
  94.                     break;
  95.                case 'S': /* Save as a NeoChrome picture */
  96.                     strcpy(picturefile, "star.neo");
  97.                     savepic();
  98.                     break;
  99.                default:
  100.                     break;
  101.                }
  102.                break;
  103.           }
  104.      vecreset();
  105. }
  106.  
  107. /*
  108. ** Restore the screen
  109. */
  110. vecreset()
  111. {
  112.      int i;
  113.  
  114.      v_clsvwk(vdihandle); /* Close the virtual workscreen */
  115.      appl_exit(); /* Remove the application from AES */
  116.      Cconws("\033H\033J"); /* Clear the screen */
  117.      Setscreen((char *)-1, (char *)-1, oldrez); /* Set resolution */
  118.      for (i = 0; i < 16; i++) /* Set the colors back to their saved values */
  119.           Setcolor(i, old_color[i]);
  120.      if (((getenv("PATH")) == 0) || (strlen(getenv("PATH")) == 0))
  121.           linea9(); /* Show mouse pointer */
  122.      else /* If called from a shell */
  123.           Cursconf(1, 0); /* Show cursor */
  124. }
  125.  
  126. /*
  127. ** Save the screen as a DEGAS or NeoChrome picture
  128. */
  129. savepic()
  130. {
  131.      int neo = 0, file; /* Assume DEGAS file */
  132.  
  133.      if (strrchr(picturefile, '.') != NULL) { /* Extender given */
  134.           if ((!strncmp(picturefile + strrchr(picturefile, '.'), ".neo", 4)) ||
  135.              (!strncmp(picturefile + strrchr(picturefile, '.'), ".NEO", 4)))
  136.                ++neo; /* Save as a NeoChrome picture */
  137.      } else
  138.           strcat(picturefile, ".pi1");
  139.      if ((file = creat(picturefile, 0)) == -1)
  140.           die("Cannot open %s.", picturefile);
  141.      if (neo) /* NeoChrome has two extra null bytes at the beginning */
  142.           if (write(file, &currez, 2) != 2)
  143.                die("Write failure on file %s.", picturefile);
  144.      if (write(file, &currez, 2) != 2) /* Write the resolution */
  145.           die("Write failure on file %s.", picturefile);
  146.      if (write(file, &new_color[0], 32) != 32) /* Write the palette info */
  147.           die("Write failure on file %s.", picturefile);
  148.      if (neo) /* NeoChrome has a 128-byte header, so we'll pad with 94 bytes */
  149.           for (neo = 0; neo < 47; ++neo) /* Recycle the variable "neo" */
  150.                if (write(file, &currez, 2) != 2)
  151.                     die("Write failure on file %s.", picturefile);
  152.      if (write(file, Physbase(), 32000) != 32000) /* Write the screen */
  153.           die("Write failure on file %s.", picturefile);
  154.      close(file); /* Done!  (that wasn't too bad, was it?) */
  155. }
  156.  
  157. /*
  158. ** This function is duplicated in starchrt.c for non-ST versions, using
  159. ** the INTERACTIVE manifest constant.
  160. */
  161. die(a,b)
  162. char *a, *b;
  163. {
  164.      char buf[80];
  165.      int i;
  166.  
  167.      if (oldrez != 99) /* See if we ever initialized the screen. */
  168.          vecreset(); /* Reset the screen to something sane */
  169.      if (!strncmp(b, "\nusage", 6)) { /* Sub in the ST's usage */
  170.           Cconws("\n\rusage:\tstar* [ Ra Dcl Scale Title Maglim Labellim ]\n");
  171.           Cconws("\ror\tstar* [ -r Ra -d Dcl -s Scale -t Title -m Maglim -l ");
  172.           Cconws("Labellim -f x.str ]\n\ror\tstar* [ -c con (3 or 4 letters ");
  173.           Cconws("chosen from con.loc) -l ... ]\n\ror\tstarst -x [ file.PI1 ");
  174.           Cconws("| file.NEO ] ... (to exit and save screen)\n\n\r");
  175.           Cconws("Portions of this program, copyright 1984, ");
  176.           Cconws("Mark Williams Company");
  177.      } else {
  178.           sprintf(buf, a, b);
  179.           Cconws(buf);
  180.      }
  181.      Cconws("\n\r"); /* Cconws does not map \n into \n\r */
  182.      /* We want to hold the screen if invoked from the GEM desktop;
  183.         the desktop doesn't usually set any environment variables,
  184.         and if getenv() does find anything, it's probably a NULL string. */
  185.      if (((getenv("PATH")) == 0) || (strlen(getenv("PATH")) == 0)) {
  186.           Cconws("press any key to continue:  "); /* Hold screen if desktop */
  187.           i = Crawcin(); /* Read raw character input */
  188.      }
  189.     exit(1);
  190. }
  191.  
  192. /*
  193. ** Functions for manipulating text.
  194. */
  195.  
  196. /*
  197. ** This function sets the point size for text. (not applicable)
  198. */
  199. vecsize (points)
  200. int points;
  201. {
  202. }
  203.  
  204. /*
  205. ** This function puts text on the screen.
  206. */
  207. vecsyms (x, y, s)
  208. int x,y;
  209. char *s;
  210. {
  211.      register char *ptr;
  212.      register unsigned int tmp;
  213.  
  214.      if (*s == '\0') /* Don't bother if the string is empty */
  215.           return;   /* (A null char can make linea8() crash!) */
  216.      fontp = la_init.li_a1[0];  /* 6x6 system font */
  217.      FBASE = fontp->font_data; /* Pointer to start of font form */
  218.      FWIDTH = fontp->font_width; /* Width of font form */
  219.      DELY = fontp->font_height; /* Height of character in font */
  220.  
  221.      DSTX = xadjust(x);
  222.      if ((DSTY = yadjust(y)) > 2)
  223.           DSTY -= 2; /* This vertically centers the text on the line */
  224.      if (DSTY > 191)
  225.           DSTY = 191; /* Make sure the bottom line shows up */
  226.      ptr = s;
  227.      do { /* Output the characters until the end of the string is hit */
  228.           if (!iscntrl(*ptr)) {
  229.                tmp = *ptr - fontp->font_low_ade; /* Find the character data */
  230.                SRCX = fontp->font_char_off[tmp]; /* within the font data */
  231.                DELX = fontp->font_char_off[tmp + 1] - SRCX;
  232.                /* Check screen boundaries */
  233.                if ((DSTX > 0) && (DSTX < 311) && (DSTY > 0))
  234.                     if (isspace(*ptr)) {
  235.                          WMODE = 1; /* Writing mode = transparent */
  236.                          linea8();
  237.                          WMODE = 0; /* Writing mode = replace */
  238.                     } else 
  239.                          linea8(); /* Line A trap for text blit routine */
  240.           }
  241.      } while (*++ptr != '\0');
  242. }
  243.  
  244. /*
  245. ** This function puts text on the screen using the greek alphabet.
  246. ** (Well, not yet, but someday ... :-))
  247. */
  248. vecsymsgk(s, x, y)
  249. char *s;
  250. {
  251.      vecsyms(s, x, y);
  252. }
  253.  
  254. /*
  255. ** Functions for drawing points and lines.
  256. */
  257.  
  258. /*
  259. ** Change the current position of x and y.
  260. */
  261. vecmove (x, y)
  262. int x,y;
  263. {
  264.      CURRX = x;
  265.      CURRY = y;
  266. }
  267.  
  268. /*
  269. ** Move to a new location (x1, y1) and draw a solid line to (x2, y2).
  270. */
  271. vecmovedraw (x1, y1, x2, y2)
  272. int x1, y1, x2, y2;
  273. {
  274.      vecmove(x1, y1);
  275.      vecdraw(x2, y2);
  276. }
  277.  
  278. /*
  279. ** Draw a solid line to (x,y)
  280. */
  281. vecdraw (x, y)
  282. int x,y;
  283. {
  284.      if (linemode != 'S') {
  285.           linemode = 'S';
  286.           COLBIT0 = 1; /* Set the bit plane for line drawing (color 15) */
  287.           COLBIT1 = 1;
  288.           COLBIT2 = 1;
  289.           COLBIT3 = 1;
  290.      }
  291.      X1 = xadjust(CURRX);
  292.      Y1 = yadjust(CURRY);
  293.      X2 = xadjust(CURRX = x);
  294.      Y2 = yadjust(CURRY = y);
  295.      linea3(); /* Line blit routine */
  296. }
  297.  
  298. /*
  299. ** Draw a dotted line (dark green on the ST) to (x,y)
  300. */
  301. vecdrawdot(x, y)
  302. {
  303.      if (linemode != 'D') {
  304.           linemode = 'D';
  305.           COLBIT0 = 1; /* Set the bit plane for line drawing (color 13) */
  306.           COLBIT1 = 0;
  307.           COLBIT2 = 1;
  308.           COLBIT3 = 1;
  309.      }
  310.      X1 = xadjust(CURRX);
  311.      Y1 = yadjust(CURRY);
  312.      X2 = xadjust(CURRX = x);
  313.      Y2 = yadjust(CURRY = y);
  314.      linea3();
  315. }
  316.  
  317. /*
  318. ** Draw a hyphenated line (dark red on the ST) to (x,y)
  319. */
  320. vecdrawhyph(x, y)
  321. {
  322.      if (linemode != 'H') {
  323.           linemode = 'H';
  324.           COLBIT0 = 0; /* Set the bit plane for line drawing (color 14) */
  325.           COLBIT1 = 1;
  326.           COLBIT2 = 1;
  327.           COLBIT3 = 1;
  328.      }
  329.      X1 = xadjust(CURRX);
  330.      Y1 = yadjust(CURRY);
  331.      X2 = xadjust(CURRX = x);
  332.      Y2 = yadjust(CURRY = y);
  333.      linea3();
  334. }
  335.  
  336. /*
  337. ** Draw a horizontal line.
  338. */
  339. drawlen (x, y, dx, dy, len)
  340. int x, y, dx, dy, len;
  341. {
  342.      if (linemode != 'S') {
  343.           linemode = 'S';
  344.           COLBIT0 = 1; /* Set the bit plane for line drawing (color 15) */
  345.           COLBIT1 = 1;
  346.           COLBIT2 = 1;
  347.           COLBIT3 = 1;
  348.      }
  349.      X1 = xadjust(x + dx);
  350.      Y1 = yadjust(y + dy);
  351.      X2 = xadjust(CURRX = x + dx + len - 1);
  352.      Y2 = yadjust(CURRY = y + dy);
  353.      linea3();
  354. }
  355.  
  356. /*
  357. ** Functions for astronomical objects.
  358. */
  359.  
  360. /*
  361. ** Draw the sun or a planet
  362. */
  363. drawPlan(x, y, mag, type, color)
  364. int x, y, mag, type;
  365. char *color;
  366. {
  367.      if (type == 'S')
  368.           INTIN[0] = 10; /* Yellow for the Sun */
  369.      else if ((type == 'M') || (type == 'V'))
  370.           INTIN[0] = 11; /* Pink for inferior planets (Mercury or Venus) */
  371.      else
  372.           INTIN[0] = 12; /* Purple for superior planets (m, J, s, U, or N) */
  373.      PTSIN[0] = xadjust(CURRX = x);
  374.      PTSIN[1] = yadjust(CURRY = y);
  375.      if (linea2() == 0) /* See if there's anything there already */
  376.           linea1(); /* Put a pixel on the screen */
  377. }
  378.  
  379. /*
  380. ** Draw a star.
  381. */
  382. drawStar(x, y, mag, type, color)
  383. int x, y, mag, type;
  384. char *color;
  385. {
  386.      if (mag > 6)
  387.           INTIN[0] = 6;
  388.      else if (mag < 1)
  389.           INTIN[0] = 1;
  390.      else
  391.           INTIN[0] = mag; /* No conversion necessary, direct map into palette */
  392.      if (mag < 2) /* Brightest stars will be in color if possible */
  393.           if (color != NULL)
  394.                if ((color[0] == 'O') || (color[0] == 'B'))
  395.                     INTIN[0] = 8; /* Color register 8 holds blue */
  396.                else if ((color[0] == 'K') || (color[0] == 'M'))
  397.                     INTIN[0] = 9; /* Color register 9 holds red */
  398.      PTSIN[0] = xadjust(CURRX = x);
  399.      PTSIN[1] = yadjust(CURRY = y);
  400.      if (mag < 1)
  401.           drawBigStar(x, y); /* Bright stars clobber anything under them */
  402.      else if (linea2() == 0) /* See if there's anything there already */
  403.                linea1();
  404. }
  405.  
  406. /*
  407. ** Draw a bright star as a cross shape.
  408. */
  409. drawBigStar(x, y)
  410. int x, y;
  411. {
  412.      linea1(); /* x, y */
  413.      --PTSIN[0];
  414.      linea1(); /* x-1, y */
  415.      ++PTSIN[0];
  416.      --PTSIN[1];
  417.      linea1(); /* x, y-1 */
  418.      PTSIN[1] += 2;
  419.      linea1(); /* x, y+1 */
  420.      ++PTSIN[0];
  421.      --PTSIN[1];
  422.      linea1(); /* x+1, y */
  423. }
  424.  
  425. /*
  426. ** Draw a nebula. ('type' = 'D' for diffuse, 'P' for planetary)
  427. */
  428. drawNebu(x, y, mag, type, color)
  429. int x, y, mag, type;
  430. char *color;
  431. {
  432.      /* This isn't as clever as cstar() in starimag.c, but it's fast */
  433.      INTIN[0] = 7; /* Make 'em faint, with this shape: */
  434.      PTSIN[0] = xadjust(CURRX = x) - 1; /*         **       */
  435.      PTSIN[1] = yadjust(CURRY = y);     /*        *  *      */
  436.      linea1(); /* x-1, y                           **       */
  437.      ++PTSIN[1];
  438.      linea1(); /* x-1, y+1 */
  439.      ++PTSIN[0];
  440.      ++PTSIN[1];
  441.      linea1(); /* x, y+2 */
  442.      PTSIN[1] -= 3;
  443.      linea1(); /* x, y-1 */
  444.      ++PTSIN[0];
  445.      ++PTSIN[1];
  446.      linea1(); /* x+1, y */
  447.      ++PTSIN[1];
  448.      linea1(); /* x+1, y+1 */
  449. }
  450.  
  451. /*
  452. ** Draw a galaxy. ('type' = 'P' for sphere, 'S' for spiral)
  453. */
  454. drawGalx(x, y, mag, type, color)
  455. int x, y, mag, type;
  456. char *color;
  457. {
  458.      int i;
  459.  
  460.      CURRX = x;
  461.      CURRY = y;
  462.      INTIN[0] = 7; /* Make 'em faint, with this shape: */
  463.      PTSIN[0] = xadjust(CURRX = x) - 2; /*        **  *   */
  464.      PTSIN[1] = yadjust(CURRY = y);     /*      ******    */
  465.      for (i = 0; i < 6; ++i) {          /*     *  **      */
  466.           PTSIN[0] += 1;
  467.           linea1(); /* (x-2)+i, y */
  468.      }
  469.      ++PTSIN[0];
  470.      --PTSIN[1];
  471.      linea1(); /* x+4, y-1 */
  472.      PTSIN[0] -= 3;
  473.      linea1(); /* x+1, y-1 */
  474.      --PTSIN[0];
  475.      linea1(); /* x, y-1 */
  476.      PTSIN[1] += 2;
  477.      linea1(); /* x, y+1 */
  478.      ++PTSIN[0];
  479.      linea1(); /* x+1, y+1 */
  480.      PTSIN[0] -= 4;
  481.      linea1(); /* x-3, y+1 */
  482. }
  483.  
  484. /*
  485. ** Draw a cluster. ('type' = 'G' for glob., 'O' for open, 'C' for Galactic)
  486. */
  487. drawClus(x, y, mag, type, color)
  488. int x, y, mag, type;
  489. char *color;
  490. {
  491.      INTIN[0] = 7; /* Make 'em faint, with this shape: */
  492.      PTSIN[0] = xadjust(CURRX = x);     /*         * *      */
  493.      PTSIN[1] = yadjust(CURRY = y);     /*        * * *     */
  494.      linea1(); /* x, y                             * *      */
  495.      PTSIN[0] -= 2;
  496.      linea1(); /* x-2, y */
  497.      ++PTSIN[0];
  498.      --PTSIN[1];
  499.      linea1(); /* x-1, y-1 */
  500.      PTSIN[0] += 2;
  501.      linea1(); /* x+1, y-1 */
  502.      PTSIN[1] += 2;
  503.      linea1(); /* x+1, y+1 */
  504.      PTSIN[0] -= 2;
  505.      linea1(); /* x-1, y+1 */
  506.      PTSIN[0] += 3;
  507.      --PTSIN[1];
  508.      linea1(); /* x+2, y */
  509. }
  510.