[net.micro.cbm] Converting ray-trace pictures for display on C64s

bahilchie@watnot.UUCP (Brian Hilchie) (08/22/86)

Here is a program to convert output from the ray tracing program (v2.0)
recently posted to net.sources into a format suitable for display on a
C64.

Enclosed is a shell archive containing:

    tracer.c, macros.h -- Modified versions of files originally distributed
                          with the tracer program. The program must be
                          remade with these new versions.

    cnv.c --              The conversion program.  This program takes as
                          input the output file produced by the tracer
                          program annd writes as output a file which may
                          displayed on a 64. The default input and output
                          files are data.dis and and pic64, but these
                          may be changed with the options -i filename
                          and -o filename.

    display.uue --        A uuencoded BASIC program to display pictures
                          output by cnv on a C64.

Brian Hilchie
...ihnp4!watmath!watnot!bahilchie

-------------------------------------------------------------------------------

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watnot!bahilchie on Thu Aug 21 22:10:16 EDT 1986
# Contents:  tracer.c macros.h cnv.c display.uue
 
echo x - tracer.c
sed 's/^@//' > "tracer.c" <<'@//E*O*F tracer.c//'


/***************************************************************
 *            basic ray tracing package tracer2.0              *
 *            version 0.0 done 6/1/86-6/10/86                  *
 *            version 1.0 released 6/29/86                     *
 *            version 2.0 released 7/5/86                      *
 *            by friedrich knauss (one tired programmer)       *
 ***************************************************************/
#include <stdio.h>
#include <math.h>
#include "rtd.h"
#include "macros.h"

#define  XSIZE  160
#define  YSIZE  200


FILE * fp;
double  suzie[300][300],
        sam = 1.0;
int     xsue,
        ysue;
struct ball *bl[150];
int     level,
        nob;
struct sphere   ls;

main (argc, argv)
int     argc;
char  **argv;
{
    FILE * df, *texfile;
    static double   xco,
                    yco;
    struct ray  rr;
    struct vector   vp;
    double  x,
            y,
            z;
    double  xfac, yfac, offset;
    int     i,
            in = 0,
            out = 0,
            tex = 0,
            xc, yc;
    int     c;

/* command interp */

    for (i = 1; i < argc; i++) {
	if (argv[i][0] != '-')
	    booboo ("Options strt with a '-' bozo");
	c = argv[i][1];

	switch (c) {
	    case ('i'): /* input file */
		if (in)
		    booboo ("Sorry, but you may only have one input file");
		in = 1;
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    df = stdin;
		else
		    if ((df = fopen (argv[++i], "r")) == NULL)
			booboo ("input file not found");
		break;
	    case ('o'): /* output file */
		if (out)
		    booboo ("Sorry, but you may have only one output file");
		out = 1;
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    fp = stdout;
		else
		    fp = fopen (argv[++i], "w");
		break;
	    case ('s'): /* susie file */
		if (tex)
		    booboo ("Sorry, but you may have only one image file");
		if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
		    booboo ("-s requires an argument");
		tex = 1;
		if ((texfile = fopen (argv[++i], "r")) == NULL)
		    booboo ("image file not found");
		break;
		booboo ("this line shouldn't do anything");
	    case ('S'): /* amount of susie */
		if (argv[i][2] < '0' || argv[i][2] > 9)
		    booboo ("-S needs a numerical argument");
		sam = atof (&(argv[i][2]));
		break;
	    default: 
		booboo ("Unrecognized option. Better try again");
	}
    }


    if (!in)
	if ((df = fopen ("bdata.i", "r")) == NULL)
	    booboo ("bdata.i not found");
    if (!out)
	fp = fopen ("data.dis", "w");
    if (!tex)
	if ((texfile = fopen ("pat.def", "r")) == NULL)
	    booboo ("pat.def not found");


/* if you can't figure *this* out, you should go home */
    nob = g_bal (df);
    g_bod (texfile);



    MV (95.0, 140.0, -200.0, vp);
    MV (0.0, 900.0, 0.0, ls.cent);
    ls.rad = 40;
    fprintf (fp, "%d %d\n", XSIZE, YSIZE);

    xfac = (XMAX-XMIN)/SCALE;
    yfac = (YMAX-YMIN)/SCALE;
    offset = (SCALE-1.0)/2.0;

    for (yc = YSIZE-1; yc >= 0; yc--)
	for (xc = 0; xc < XSIZE; xc++) {
            xco = (double) xc/(XSIZE-1)*xfac + XMIN + xfac*offset;
            yco = (double) yc/(YSIZE-1)*yfac + YMIN + yfac*offset;
	    MV (xco, yco, 0.0, rr.org);
	    SV (rr.dir, rr.org, vp);
	    fprintf (fp, "%c", shade (&rr));
	}
}

booboo (str)
char   *str; {
    printf ("%s\n", str);
    exit (-1);
}
@//E*O*F tracer.c//
chmod u=rw,g=r,o=r tracer.c
 
echo x - macros.h
sed 's/^@//' > "macros.h" <<'@//E*O*F macros.h//'
/* some of the most important stuff in the program */
#define DOT(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)
/* returns dot product of two vectors */
#define LN2(v)	   (DOT(v,v))
/* returns the square of the length of a vector */
#define LEN(v)	   sqrt(LN2(v))
/* guess */
#define XZL(v)	   sqrt(v.x*v.x+v.z*v.z)
/* returns the component in the xz plane of a vector */
#define SCMLT(sc,vct) vct.x*= sc;vct.y*= sc;vct.z*= sc;vct.l*= sc;
/* multiplies a vetor by a scalar */
#define MV(a,b,c,v)   v.x= a;v.y= b;v.z= c;
/* makes a vector. wouldn't need this with c++ */
#define SV(t,u,v)  t.x=u.x-v.x;t.y=u.y-v.y;t.z=u.z-v.z;
/*subtract vector t=u-v */
#define AV(t,u,v)  t.x=u.x+v.x;t.y=u.y+v.y;t.z=u.z+v.z;
/* add vector t=u+v */
#define MTV(v1,m,v2) MV(DOT(m.x,v2),DOT(m.y,v2),DOT(m.z,v2),v1)
/* multiply transpose matrix by vector. v1=m*v2 */

#define LEVEL 5/* levels of recursion */
#define RLEV  3/*don't want as many inside the ball, takes forever as it is*/

#define XMIN 10.0
#define XMAX 220.0
#define YMIN 10.0
#define YMAX 170.0
/* window size,  virtual units */
#define SCALE  1.0
/* maginification factor */
@//E*O*F macros.h//
chmod u=rw,g=r,o=r macros.h
 
echo x - cnv.c
sed 's/^@//' > "cnv.c" <<'@//E*O*F cnv.c//'
#include <stdio.h>

#define  XSIZE    160
#define  YSIZE    200
#define  NBLOCKS  1000

#define  block(x,y)  ( (y/8)*40 + x/4 )
#define  cnvcol(x)   ( x/51 <= 4 ? x/51 : 4 )


int colmap[] = { 0, 11, 12, 15, 1 };

struct {
          int nasgn;      /* numbers of colours used */
          int cols[3];
} colasgn[NBLOCKS];

int bitmap[XSIZE][YSIZE];


main (argc, argv)
int argc;
char **argv;
{
    FILE *f;
    int c;
    int x, y;
    char *infile =  "data.dis";
    char *outfile = "pic64";

    while (--argc > 0)
        if (strcmp (*++argv, "-i") == 0)
            if (--argc > 0)
                infile = *++argv;
            else
                error ("Missing input file name");
        else if (strcmp (*argv, "-o") == 0)
            if (--argc > 0)
                outfile = *++argv;
            else
                error ("Missing output file name");
        else
            error ("Unknown option");

    f = fopen (infile, "r");
    if (f == NULL)
        error ("Can't open input file");

    while ( (c = getc(f)) != '\n')
        ;

    for (c = 0; c < NBLOCKS; c++)
       {
        colasgn[c].nasgn = 0;
        colasgn[c].cols[0] = 0;
        colasgn[c].cols[1] = 0;
        colasgn[c].cols[2] = 0;
       }

    for (y = 0; y < YSIZE; y++)
        for (x = 0; x < XSIZE; x++)
            insert (getc(f), x, y);

    fclose (f);

    f = fopen (outfile, "w");
    if (f == NULL)
        error ("Can't open output file");

    output (f);
    fclose (f);
}



error (str)
char *str;
{
    fprintf (stderr, "%s\n", str);
    exit (1);
}



insert (byte, x, y)
{
    int c, col;

    col = cnvcol (byte);
    c = find (col, x, y);
    if (c < 0)
        c = find (col-1, x, y);
    bitmap[x][y] = c;
}



find (col, x, y)
{
    int blk, i, c;

    if (col == 0)
        c = 0;
    else
       {
        blk = block (x, y);
        for (i = 0; i < colasgn[blk].nasgn && colasgn[blk].cols[i] != col; i++)
            ;
        if (i < colasgn[blk].nasgn)
            c = i + 1;
        else if (colasgn[blk].nasgn < 3)
           {
            i = colasgn[blk].nasgn++;
            colasgn[blk].cols[i] = col;
            c = i + 1;
           }
        else
            c = -1;
       }
}



output (f)
FILE *f;
{
    int blk, row, column, x, y, byte;

    for (blk = 0; blk < NBLOCKS; blk++)
        for (row = 0; row < 8; row++)
           {
            byte = 0;
            for (column = 0; column < 4; column++)
               {
                x = (blk%40)*4 + column;
                y = (blk/40)*8 + row;
                byte = ( byte << 2 ) | bitmap[x][y];
               }
            putc (byte, f);
           }

    for (blk = 0; blk < NBLOCKS; blk++)
        putc ((colmap[colasgn[blk].cols[0]] << 4) |
               colmap[colasgn[blk].cols[1]], f);

    for (blk = 0; blk < NBLOCKS; blk++)
        putc (colmap[colasgn[blk].cols[2]], f);
}
@//E*O*F cnv.c//
chmod u=rw,g=r,o=r cnv.c
 
echo x - display.uue
sed 's/^@//' > "display.uue" <<'@//E*O*F display.uue//'
begin 644 display
M 0@K" H A2*3$1$1$1$1$1$1$1$1!5!)0U154D4@1DE,12!.04U%(CM.) !!
M"!0 ES4S,C@P+# ZES4S,C@Q+#  5P@> )<U,S(W,BS"*#4S,C<R*; X ($(
M* "7-3,R-C4LPB@U,S(V-2FP,S(ZES4S,C<P+,(H-3,R-S IL#$V (\(,@"?
M,BPX+#(L3B0 F0@\ )XR,S T * (1@"@,@"R"%  H4XD.HM.)+(B(HDX, #*
M"%H ES4S,C<R+,(H-3,R-S(IKS(T-P#V"&0 ES4S,C8U+,(H-3,R-C4IKS(R
M,SJ7-3,R-S LPB@U,S(W,"FO,C,Y /X(;@"),3    "B B#&_ZD@A?R@ (3[
M(,__D?O(T +F_,! T/*E_,D_T.RI!(7\H "$^R#/_Y'[R- "YOS Z-#RI?S)
F!]#LJ=B%_*  A/L@S_^1^\C0 N;\P.C0\J7\R=O0["#,_V"JJJK 
 
end
@//E*O*F display.uue//
chmod u=rw,g=r,o=r display.uue
 
exit 0