amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (09/04/90)
Submitted-by: David Schanen <mtv@milton.u.washington.edu>
Posting-number: Volume 90, Issue 252
Archive-name: applications/dkbtrace-2.01/part04
#!/bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 10)."
# Contents: src/DumpToIFF.c src/ibm.c src/iff.c src/objects.c
# src/quadrics.c
# Wrapped by tadguy@abcfd20 on Mon Sep 3 19:21:18 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/DumpToIFF.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/DumpToIFF.c'\"
else
echo shar: Extracting \"'src/DumpToIFF.c'\" \(13811 characters\)
sed "s/^X//" >'src/DumpToIFF.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X* dumptoiff.c
X*
X* from DKBTrace (c) 1990 David Buck
X*
X* This file converts the raw output from the ray tracer into HAM files.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file. If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author. It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software. The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them. Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X* David Buck
X* 22C Sonnet Cres.
X* Nepean Ontario
X* Canada, K2H 8W7
X*
X* I can also be reached on the following bulleton boards:
X*
X* ATX (613) 526-4141
X* OMX (613) 731-3419
X* Mystic (613) 731-0088 or (613) 731-6698
X*
X* Fidonet: 1:163/109.9
X* Internet: David_Buck@Carleton.CA
X*
X*
X*****************************************************************************/
X
X
X#include <stdio.h>
X#include <exec/types.h>
X#include <intuition/intuition.h>
X#include <graphics/display.h>
X#include <libraries/dos.h>
X#include <proto/all.h>
X#include "config.h"
X#include "iff.h"
X#include "dumptoiff.h"
X#include "dumproto.h"
X
Xstruct IntuitionBase *IntuitionBase;
Xstruct GfxBase *GfxBase;
Xstruct Screen *s;
X
X#define extract_red(x) ((x & 0xF00) >> 8)
X#define extract_green(x) ((x & 0x0F0) >> 4)
X#define extract_blue(x) (x & 0x00F)
X
Xstruct NewScreen MyScreen =
X {
X 0, 0,
X SCREEN_WIDTH, SCREEN_HEIGHT,
X 6,
X 0, 1,
X INTERLACE | HAM,
X 0,
X NULL,
X (UBYTE *) "DumpToIFF",
X NULL,
X NULL
X };
X
XUWORD ColourTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666,
X 0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd,
X 0xeee, 0xfff };
X
XLONG last_y = -1;
XIMAGE Raw_Image;
X
XFILE *fp, *palette_file, *output_palette_file;
Xchar input_filename[100], palette_filename[100], output_filename[100];
Xchar output_palette_filename[100];
X
X
Xint output_file, read_palette, write_palette, dithering;
Xvoid get_parameters(int argc, char **argv);
X
Xvoid main (argc, argv)
X int argc;
X char **argv;
X {
X unsigned int red, green, blue, i;
X unsigned int x, y, index;
X
X if (argc < 2)
X {
X printf ("\nUsage: DumpToIFF [options] <dump_filename> <iff_file_name> [<palette_filename>]\n");
X printf (" Options:\n");
X printf (" -d - No dithering\n");
X printf (" -pfilename - Write a palette file\n");
X exit(0);
X }
X
X Close_Threshold = 5;
X
X fp = NULL;
X read_palette = FALSE;
X write_palette = FALSE;
X output_file = FALSE;
X dithering = TRUE;
X
X IntuitionBase = (struct IntuitionBase *)
X OpenLibrary ("intuition.library",INT_REV);
X if (IntuitionBase == NULL)
X exit(FALSE);
X
X GfxBase = (struct GfxBase *)
X OpenLibrary ("graphics.library", GR_REV);
X if (GfxBase == NULL)
X exit(FALSE);
X
X get_parameters(argc, argv);
X
X printf ("Reading raw file\n");
X read_raw_image (&Raw_Image, input_filename);
X
X
X if (dithering) {
X printf ("Dithering...\n");
X dither(&Raw_Image);
X }
X
X printf ("Processing...\n");
X if (read_palette) {
X if ((palette_file = fopen (palette_filename, "r")) == NULL) {
X display_close();
X exit(FALSE);
X }
X
X for (i = 0 ; i < 16 ; i++) {
X if (fscanf (palette_file, "%d %d %d", &red, &green, &blue) != 3) {
X printf ("Error reading palette file\n");
X exit (1);
X }
X
X ColourTbl[i] = ((red & 0x0f) << 8) |
X ((green & 0x0f) << 4) | (blue & 0x0f);
X }
X }
X else {
X start_recording_colours();
X
X for (y = 0 ; y < Raw_Image.height ; y++) {
X for (x = 0 ; x < Raw_Image.width ; x++) {
X index = y*Raw_Image.width + x;
X process (x, y, Raw_Image.red[index],
X Raw_Image.green[index],
X Raw_Image.blue[index]);
X
X }
X }
X choose_palette();
X }
X
X /* Write out the palette file */
X if (write_palette) {
X if ((output_palette_file = fopen (output_palette_filename, "w")) == NULL)
X {
X printf ("Cannot create palette file\n");
X exit (1);
X }
X
X
X for (i = 0 ; i < 16 ; i++)
X fprintf (output_palette_file, "%d %d %d\n",
X extract_red(ColourTbl[i]),
X extract_green(ColourTbl[i]),
X extract_blue(ColourTbl[i]));
X
X
X fclose(output_palette_file);
X }
X
X printf ("Displaying...\n");
X
X MyScreen.Width = Raw_Image.width+1;
X MyScreen.Height = Raw_Image.height;
X if ((s = (struct Screen *) OpenScreen (&MyScreen))
X == NULL)
X exit (FALSE);
X
X ShowTitle (s, FALSE);
X
X
X SetAPen (&(s->RastPort), 7L);
X RectFill (&(s -> RastPort), 0L, 0L, Raw_Image.width, Raw_Image.height-1);
X
X LoadRGB4 (&(s->ViewPort), ColourTbl, 16L);
X
X for (y = 0 ; y < Raw_Image.height ; y++) {
X for (x = 0 ; x < Raw_Image.width ; x++) {
X index = y*Raw_Image.width + x;
X display_plot (x, y, Raw_Image.red[index],
X Raw_Image.green[index],
X Raw_Image.blue[index]);
X }
X }
X
X if (output_file)
X ConvertToIFF(output_filename);
X
X printf ("Finished\n");
X display_close();
X }
X
Xvoid get_parameters (argc, argv)
X int argc;
X char **argv;
X {
X int i, filename_number;
X
X filename_number = 0;
X for (i = 1 ; i < argc ; i++) {
X if (argv[i][0] == '-')
X switch (argv[i][1]) {
X case 'd': dithering = FALSE;
X break;
X
X case 'p': strcpy (output_palette_filename, &argv[i][2]);
X write_palette = TRUE;
X break;
X
X default: printf ("Unknown option\n");
X break;
X }
X else
X switch (filename_number) {
X case 0: strcpy (input_filename, argv[i]);
X filename_number++;
X break;
X
X case 1: strcpy (output_filename, argv[i]);
X output_file = TRUE;
X filename_number++;
X break;
X
X case 2: strcpy (palette_filename, argv[i]);
X filename_number++;
X read_palette = TRUE;
X break;
X
X default: printf ("Too many filenames in commandline\n");
X exit(1);
X }
X }
X if (filename_number == 0) {
X printf ("No input file specified\n");
X exit(1);
X }
X }
X
X
Xvoid display_close ()
X {
X if (fp != NULL)
X fclose (fp);
X CloseScreen (s);
X CloseLibrary (GfxBase) ;
X CloseLibrary (IntuitionBase) ;
X }
X
Xvoid display_plot (x, y, new_red, new_green, new_blue)
X LONG x, y, new_red, new_green, new_blue;
X {
X LONG colour, newline;
X
X new_red &= 0xFF;
X new_green &= 0xFF;
X new_blue &= 0xFF;
X
X new_red /= 16;
X new_green /= 16;
X new_blue /= 16;
X
X newline = 0;
X if (last_y != y) {
X newline = 1;
X last_y = y;
X reset_colours();
X SetAPen (&(s -> RastPort), 0);
X WritePixel (&(s -> RastPort), 0, y);
X }
X
X colour = best_colour (new_red, new_blue, new_green);
X SetAPen (&(s -> RastPort), colour);
X WritePixel (&(s -> RastPort), x+1, y);
X }
X
X
Xvoid dither (Image)
X IMAGE *Image;
X {
X long index;
X short i, j, new_red, new_green, new_blue,
X red_error, green_error, blue_error;
X
X red_error = 0;
X green_error = 0;
X blue_error = 0;
X
X for (j = 0 ; j < Image->height ; j++)
X for (i = 0 ; i < Image->width ; i++) {
X index = j * Image->width + i;
X red_error = Image->red[index] % 16;
X green_error = Image->green[index] % 16;
X blue_error = Image->blue[index] % 16;
X
X if (i < Image->width-1) {
X new_red = Image->red[index+1] + red_error * 7 / 16;
X new_green = Image->green[index+1] + green_error * 7 / 16;
X new_blue = Image->blue[index+1] + blue_error * 7 / 16;
X Image->red[index+1] = (new_red>255) ? 255 : new_red;
X Image->green[index+1] = (new_green>255) ? 255 : new_green;
X Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
X }
X
X if (j < Image->height-1) {
X index += Image->width;
X if (i != 0) {
X new_red = Image->red[index-1] + red_error * 3 / 16;
X new_green = Image->green[index-1] + green_error * 3 / 16;
X new_blue = Image->blue[index-1] + blue_error * 3 / 16;
X Image->red[index-1] = (new_red>255) ? 255 : new_red;
X Image->green[index-1] = (new_green>255) ? 255 : new_green;
X Image->blue[index-1] = (new_blue>255) ? 255 : new_blue;
X }
X
X
X new_red = Image->red[index] + red_error * 5 / 16;
X new_green = Image->green[index] + green_error * 5 / 16;
X new_blue = Image->blue[index] + blue_error * 5 / 16;
X Image->red[index] = (new_red>255) ? 255 : new_red;
X Image->green[index] = (new_green>255) ? 255 : new_green;
X Image->blue[index] = (new_blue>255) ? 255 : new_blue;
X
X if (i < Image->width-1) {
X new_red = Image->red[index+1] + red_error / 16;
X new_green = Image->green[index+1] + green_error / 16;
X new_blue = Image->blue[index+1] + blue_error / 16;
X Image->red[index+1] = (new_red>255) ? 255 : new_red;
X Image->green[index+1] = (new_green>255) ? 255 : new_green;
X Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
X }
X }
X }
X }
X
X
Xvoid process (x, y, new_red, new_green, new_blue)
X LONG x, y, new_red, new_green, new_blue;
X {
X LONG newline;
X
X new_red &= 0xFF;
X new_green &= 0xFF;
X new_blue &= 0xFF;
X
X new_red /= 16;
X new_green /= 16;
X new_blue /= 16;
X
X newline = 0;
X if (last_y != y) {
X newline = 1;
X last_y = y;
X reset_colours();
X }
X
X record_colours (new_red, new_green, new_blue);
X }
X
X
Xvoid ConvertToIFF(file_name)
X char *file_name;
X {
X char *buffer;
X BPTR file;
X BOOL PutPict();
X
X if ((file = Open (file_name, MODE_NEWFILE)) == 0) {
X printf ("\nCannot open IFF file\n");
X exit (0);
X }
X
X buffer = malloc(BUFFER_SIZE);
X if (PutPict (file, &(s->ViewPort), buffer, BUFFER_SIZE))
X printf ("\nIFF write error\n");
X Close (file);
X }
X
Xint read_raw_byte(f)
X FILE *f;
X {
X int c;
X if ((c = getc(f)) == EOF)
X return (-1);
X return (c);
X }
X
Xint read_raw_word(f)
X FILE *f;
X {
X int byte1, byte2;
X
X byte1 = read_raw_byte(f);
X if (byte1 == -1)
X return(-1);
X
X byte2 = read_raw_byte(f);
X if (byte2 == -1)
X return(-1);
X
X return (byte1 + byte2*256);
X }
X
Xvoid read_raw_image(Image, filename)
X IMAGE *Image;
X char *filename;
X {
X FILE *f;
X int byte, i, index, row, pixels;
X
X if ((f = fopen(filename, "rb")) == NULL) {
X printf ("Cannot open raw file %s\n", filename);
X exit(1);
X }
X
X Image->width = read_raw_word(f);
X if (Image->width == -1) {
X printf ("Cannot read size in dump file\n");
X exit(1);
X }
X
X Image->height = read_raw_word(f);
X if (Image->height == -1) {
X printf ("Cannot read size in dump file: %s\n", filename);
X exit(1);
X }
X
X pixels = Image->width * Image->height;
X
X if (((Image->red = (unsigned char *) malloc(pixels))==NULL) ||
X ((Image->green = (unsigned char *) malloc(pixels))==NULL) ||
X ((Image->blue = (unsigned char *) malloc(pixels))==NULL)) {
X printf ("Cannot allocate memory for picture: %s\n", filename);
X exit(1);
X }
X
X for (i = 0 ; i < pixels ; i++) {
X Image->red[i] = 0;
X Image->green[i] = 0;
X Image->blue[i] = 0;
X }
X
X row = read_raw_word(f);
X while (row != -1) {
X for (i = 0 ; i < Image->width ; i++) {
X index = row*Image->width + i;
X
X byte = read_raw_byte(f);
X if (byte == -1) {
X printf ("Unexpected end of file in raw image: %s\n", filename);
X exit(1);
X }
X Image->red[index] = byte;
X }
X
X for (i = 0 ; i < Image->width ; i++) {
X index = row*Image->width + i;
X
X byte = read_raw_byte(f);
X if (byte == -1) {
X printf ("Unexpected end of file in raw image: %s\n", filename);
X exit(1);
X }
X Image->green[index] = byte;
X }
X
X for (i = 0 ; i < Image->width ; i++) {
X index = row*Image->width + i;
X
X byte = read_raw_byte(f);
X if (byte == -1) {
X printf ("Unexpected end of file in raw image: %s\n", filename);
X exit(1);
X }
X Image->blue[index] = byte;
X }
X row = read_raw_word(f);
X }
X fclose (f);
X }
END_OF_FILE
if test 13811 -ne `wc -c <'src/DumpToIFF.c'`; then
echo shar: \"'src/DumpToIFF.c'\" unpacked with wrong size!
fi
# end of 'src/DumpToIFF.c'
fi
if test -f 'src/ibm.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/ibm.c'\"
else
echo shar: Extracting \"'src/ibm.c'\" \(10840 characters\)
sed "s/^X//" >'src/ibm.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X* ibm.c
X*
X* from DKBTrace (c) 1990 David Buck
X*
X* This module implements the IBM-specific routines for DKBTrace.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file. If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author. It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software. The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them. Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X* David Buck
X* 22C Sonnet Cres.
X* Nepean Ontario
X* Canada, K2H 8W7
X*
X* I can also be reached on the following bulleton boards:
X*
X* ATX (613) 526-4141
X* OMX (613) 731-3419
X* Mystic (613) 731-0088 or (613) 731-6698
X*
X* Fidonet: 1:163/109.9
X* Internet: David_Buck@Carleton.CA
X*
X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X* Lattice BBS (708) 916-1200
X* The Information Exchange BBS (708) 945-5575
X* Stillwaters BBS (708) 403-2826
X*
X*****************************************************************************/
X
X#include "frame.h"
X#include "dkbproto.h"
X
X/* IBM VGA "colour" output routines for MS/DOS by Aaron A. Collins. This
X will deliver approximate colorings using HSV values for the approximation.
X The pallette map is divided into 4 parts - upper and lower half generated
X with full and half "value" (intensity), respectively. These halves are
X further halved by full and half saturation values of each range (pastels).
X There are three constant colors, black, white, and grey. They are used
X when the saturation is low enough that the hue becomes undefined, and which
X one is selected is based on a simple range map of "value". Usage of the
X pallette is accomplished by converting the requested color RGB into an HSV
X value. If the saturation is too low (< .25) then black, white or grey is
X selected. If there is enough saturation to consider looking at the hue,
X then the hue range of 1-63 is scaled into one of the 4 pallette quadrants
X based on its "value" and "saturation" characteristics.
X*/
X
X#include <dos.h> /* MS-DOS specific - for int86() REGS struct, etc. */
X
Xvoid set_pallette_register(unsigned, unsigned, unsigned, unsigned);
Xvoid hsv_to_rgb(DBL, DBL, DBL, unsigned *, unsigned *, unsigned *);
Xvoid rgb_to_hsv(unsigned, unsigned, unsigned, DBL *, DBL *, DBL *);
X
Xextern unsigned _stklen = 32768U; /* HUGE stack for HEAVY recursion */
Xextern int Options;
X
Xvoid display_init()
X {
X union REGS inr, outr;
X register unsigned m;
X unsigned r, g, b;
X register DBL hue, sat, val;
X
X inr.x.ax = 0x0013; /* setup to VGA 320x200x256 (mode 13H) */
X int86(0x10, &inr, &outr);
X
X inr.x.ax = 0x1010; /* make pallette register 0 black */
X inr.x.bx = 0;
X inr.h.ch = inr.h.cl = inr.h.dh = 0; /* full off */
X int86(0x10, &inr, &outr);
X
X inr.x.ax = 0x1010; /* make pallette register 64 white */
X inr.x.bx = 64;
X inr.h.ch = inr.h.cl = inr.h.dh = 63; /* full on */
X int86(0x10, &inr, &outr);
X
X inr.x.ax = 0x1010; /* make pallette register 128 dark grey */
X inr.x.bx = 128;
X inr.h.ch = inr.h.cl = inr.h.dh = 31; /* half on (dark grey) */
X int86(0x10, &inr, &outr);
X
X inr.x.ax = 0x1010; /* make pallette register 192 lite grey */
X inr.x.bx = 192;
X inr.h.ch = inr.h.cl = inr.h.dh = 48; /* 3/4 on (lite grey) */
X int86(0x10, &inr, &outr);
X
X for (m = 1; m < 64; m++) /* for the 1st 64 colors... */
X {
X sat = 0.5; /* start with the saturation and intensity low */
X val = 0.5;
X hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
X hsv_to_rgb (hue, sat, val, &r, &g, &b);
X set_pallette_register (m, r, g, b); /* set m to rgb value */
X
X sat = 1.0; /* high saturation and half intensity (shades) */
X val = 0.50;
X hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
X hsv_to_rgb (hue, sat, val, &r, &g, &b);
X set_pallette_register (m + 64, r, g, b); /* set m + 64 */
X
X sat = 0.5; /* half saturation and high intensity (pastels) */
X val = 1.0;
X
X hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
X hsv_to_rgb (hue, sat, val, &r, &g, &b);
X set_pallette_register (m + 128, r, g, b); /* set m + 128 */
X
X sat = 1.0; /* normal full HSV set at full intensity */
X val = 1.0;
X
X hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
X hsv_to_rgb (hue, sat, val, &r, &g, &b);
X set_pallette_register (m + 192, r, g, b); /* set m + 192 */
X }
X return;
X }
X
Xvoid display_finished ()
X {
X if (Options & PROMPTEXIT)
X {
X printf ("\007\007"); /* long beep */
X getch();
X }
X }
X
Xvoid display_close() /* setup to Text 80x25 (mode 3) */
X {
X union REGS inr, outr;
X
X inr.x.ax = 0x0003;
X int86(0x10, &inr, &outr);
X return;
X }
X
Xvoid display_plot (x, y, Red, Green, Blue) /* plot a single RGB pixel */
X int x, y;
X char Red, Green, Blue;
X {
X register unsigned char color;
X unsigned char far *fp;
X DBL h, s, v;
X
X /* Translate RGB value to best of 256 pallete Colors (by HSV?) */
X
X rgb_to_hsv((unsigned)Red,(unsigned)Green,(unsigned)Blue, &h, &s, &v);
X
X if (s < 0.25) /* black or white if no saturation of color... */
X {
X if (v < 0.25)
X color = 0; /* black */
X else if (v > 0.75)
X color = 64; /* white */
X else if (v > 0.5)
X color = 192; /* lite grey */
X else
X color = 128; /* dark grey */
X }
X else
X {
X color = (unsigned char) (64.0 * ((DBL)(h)) / 360.0);
X
X if (!color)
X color = 1; /* avoid black, white or grey */
X
X if (color > 63)
X color = 63; /* avoid same */
X
X if (v > 0.50)
X color |= 0x80; /* colors 128-255 for high inten. */
X
X if (s > 0.50) /* more than half saturated? */
X color |= 0x40; /* color range 64-128 or 192-255 */
X }
X
X fp = MK_FP(0xa000, 320 * y + x);
X
X *fp = color; /* normalize color to 256 */
X
X return;
X }
X
Xvoid set_pallette_register (Val, Red, Green, Blue)
X unsigned Val;
X unsigned Red, Green, Blue;
X {
X union REGS Regs;
X
X Regs.x.ax = 0x1010; /* Set one pallette register function */
X Regs.x.bx = Val; /* the pallette register to set (color #) */
X Regs.h.dh = (char) Red & 0xff; /* set the gun values (6 bits ea.) */
X Regs.h.ch = (char) Green & 0xff;
X Regs.h.cl = (char) Blue & 0xff;
X int86(0x10, &Regs, &Regs); /* Do the video interrupt */
X }
X
X/* Conversion from Hue, Saturation, Value to Red, Green, and Blue and back */
X/* From "Computer Graphics", Donald Hearn & M. Pauline Baker, p. 304 */
X
Xvoid hsv_to_rgb(hue, s, v, r, g, b)
X DBL hue, s, v; /* hue (0.0 to 360.0) s and v are from 0.0 - 1.0) */
X unsigned *r, *g, *b; /* values from 0 to 63 */
X {
X register DBL i, f, p1, p2, p3;
X register DBL xh;
X register DBL nr, ng, nb; /* rgb values of 0.0 - 1.0 */
X
X if (hue == 360.0)
X hue = 0.0; /* (THIS LOOKS BACKWARDS BUT OK) */
X
X xh = hue / 60.0; /* convert hue to be in 0,6 */
X i = floor(xh); /* i = greatest integer <= h */
X f = xh - i; /* f = fractional part of h */
X p1 = v * (1 - s);
X p2 = v * (1 - (s * f));
X p3 = v * (1 - (s * (1 - f)));
X
X switch ((int) i)
X {
X case 0:
X nr = v;
X ng = p3;
X nb = p1;
X break;
X case 1:
X nr = p2;
X ng = v;
X nb = p1;
X break;
X case 2:
X nr = p1;
X ng = v;
X nb = p3;
X break;
X case 3:
X nr = p1;
X ng = p2;
X nb = v;
X break;
X case 4:
X nr = p3;
X ng = p1;
X nb = v;
X break;
X case 5:
X nr = v;
X ng = p1;
X nb = p2;
X break;
X }
X
X *r = (unsigned)(nr * 63.0); /* Normalize the values to 63 */
X *g = (unsigned)(ng * 63.0);
X *b = (unsigned)(nb * 63.0);
X
X return;
X }
X
Xvoid rgb_to_hsv(r, g, b, h, s, v)
X unsigned r, g, b;
X DBL *h, *s, *v;
X {
X register DBL m, r1, g1, b1;
X register DBL nr, ng, nb; /* rgb values of 0.0 - 1.0 */
X register DBL nh, ns, nv; /* hsv local values */
X
X nr = (DBL) r / 255.0;
X ng = (DBL) g / 255.0;
X nb = (DBL) b / 255.0;
X
X nv = max (nr, max (ng, nb));
X m = min (nr, min (ng, nb));
X
X if (nv != 0.0) /* if no value, it's black! */
X ns = (nv - m) / nv;
X else
X ns = 0.0; /* black = no colour saturation */
X
X if (ns == 0.0) /* hue undefined if no saturation */
X {
X *h = 0.0; /* return black level (?) */
X *s = 0.0;
X *v = nv;
X return;
X }
X
X r1 = (nv - nr) / (nv - m); /* distance of color from red */
X g1 = (nv - ng) / (nv - m); /* distance of color from green */
X b1 = (nv - nb) / (nv - m); /* distance of color from blue */
X
X if (nv == nr)
X {
X if (m == ng)
X nh = 5. + b1;
X else
X nh = 1. - g1;
X }
X
X if (nv == ng)
X {
X if (m == nb)
X nh = 1. + r1;
X else
X nh = 3. - b1;
X }
X
X if (nv == nb)
X {
X if (m == nr)
X nh = 3. + g1;
X else
X nh = 5. - r1;
X }
X
X *h = nh * 60.0; /* return h converted to degrees */
X *s = ns;
X *v = nv;
X return;
X }
X
X#if !__STDC__
X
X/* ANSI Standard random number generator */
X
Xstatic unsigned long int next = 1;
X
Xint rand()
X {
X next = next * 1103515245L + 12345L;
X return ((int) (next / 0x10000L) & 0x7FFF);
X }
X
Xvoid srand(seed)
X unsigned int seed;
X {
X next = seed;
X }
X
X#endif
END_OF_FILE
if test 10840 -ne `wc -c <'src/ibm.c'`; then
echo shar: \"'src/ibm.c'\" unpacked with wrong size!
fi
# end of 'src/ibm.c'
fi
if test -f 'src/iff.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/iff.c'\"
else
echo shar: Extracting \"'src/iff.c'\" \(10876 characters\)
sed "s/^X//" >'src/iff.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X* iff.c
X*
X* from DKBTrace (c) 1990 David Buck
X*
X* This file implements a simple IFF format file reader.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file. If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author. It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software. The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them. Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X* David Buck
X* 22C Sonnet Cres.
X* Nepean Ontario
X* Canada, K2H 8W7
X*
X* I can also be reached on the following bulleton boards:
X*
X* ATX (613) 526-4141
X* OMX (613) 731-3419
X* Mystic (613) 731-0088 or (613) 731-6698
X*
X* Fidonet: 1:163/109.9
X* Internet: David_Buck@Carleton.CA
X*
X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X* Lattice BBS (708) 916-1200
X* The Information Exchange BBS (708) 945-5575
X* Stillwaters BBS (708) 403-2826
X*
X*****************************************************************************/
X
X
X#include "frame.h"
X#include "dkbproto.h"
X
Xstatic IMAGE_COLOUR *iff_colour_map;
Xstatic int colourmap_size;
Xstatic CHUNK_HEADER Chunk_Header;
X
X#define FORM 0x464f524dL
X#define ILBM 0x494c424dL
X#define BMHD 0x424d4844L
X#define CAMG 0x43414d47L
X#define CMAP 0x434d4150L
X#define BODY 0x424f4459L
X#define CMPNONE 0
X
X#define HAM 0x800
X
Xvoid iff_error ()
X {
X printf ("Invalid iff file\n");
X exit(1);
X }
X
Xint read_byte(f)
X FILE *f;
X {
X int c;
X if ((c = getc(f)) == EOF)
X iff_error();
X return (c);
X }
X
Xint read_word(f)
X FILE *f;
X {
X int result;
X
X result = read_byte(f)*256;
X result += read_byte(f);
X return (result);
X }
X
Xlong read_long(f)
X FILE *f;
X {
X int i;
X long result;
X
X result = 0;
X for (i = 0 ; i < 4 ; i++)
X result = result * 256 + read_byte(f);
X
X return (result);
X }
X
Xvoid Read_Chunk_Header (f, dest)
X FILE *f;
X CHUNK_HEADER *dest;
X {
X dest->name = read_long(f);
X dest->size = read_long(f);
X }
X
Xvoid read_iff_image(Image, filename)
X IMAGE *Image;
X char *filename;
X {
X FILE *f;
X unsigned char **row_bytes;
X int c, i, j, k, creg, index, nBytes, nBytesRead, nPlanes, compression,
X mask, byte_index, count, viewmodes;
X int Previous_Red, Previous_Green, Previous_Blue;
X
X if ((f = fopen(filename, "rb")) == NULL) {
X printf ("Cannot open IFF file %s\n", filename);
X exit(1);
X }
X
X Previous_Red = Previous_Green = Previous_Blue = 0;
X
X viewmodes = 0;
X
X while (1) {
X Read_Chunk_Header(f, &Chunk_Header);
X switch ((int) Chunk_Header.name) {
X case FORM: if (read_long(f) != ILBM)
X iff_error();
X break;
X
X case BMHD: Image->iwidth = read_word(f);
X Image->width = (DBL)Image->iwidth;
X Image->iheight = read_word(f);
X Image->height = (DBL)Image->iheight;
X read_word(f); /* x position ignored */
X read_word(f); /* y position ignored */
X nPlanes = read_byte(f);
X colourmap_size = 1<<nPlanes;
X read_byte(f); /* masking ignored */
X compression = read_byte(f); /* masking ignored */
X read_byte(f); /* pad */
X read_word(f); /* Transparent colour ignored */
X read_word(f); /* Aspect ratio ignored */
X read_word(f); /* page width ignored */
X read_word(f); /* page height ignored */
X break;
X
X case CAMG: viewmodes = (int) read_long(f); /* Viewmodes */
X if (viewmodes & HAM)
X colourmap_size = 16;
X break;
X
X case CMAP: colourmap_size = (int) Chunk_Header.size / 3;
X
X if ((iff_colour_map = (IMAGE_COLOUR *) malloc(sizeof(IMAGE_COLOUR)*colourmap_size)) == NULL)
X iff_error();
X
X for (i = 0 ; i < colourmap_size ; i++) {
X iff_colour_map[i].Red = read_byte(f);
X iff_colour_map[i].Green = read_byte(f);
X iff_colour_map[i].Blue = read_byte(f);
X }
X Previous_Red = iff_colour_map[0].Red;
X Previous_Green = iff_colour_map[0].Green;
X Previous_Blue = iff_colour_map[0].Blue;
X for (i = colourmap_size*3 ; i < Chunk_Header.size ; i++)
X read_byte(f);
X
X break;
X
X case BODY: if ((row_bytes = (unsigned char **) malloc (4*nPlanes)) == NULL) {
X printf ("Not enough memory\n");
X exit(1);
X }
X
X for (i = 0 ; i < nPlanes ; i++)
X if ((row_bytes[i] = (unsigned char *) malloc((Image->iwidth+7)/8)) == NULL) {
X printf ("Not enough memory\n");
X exit(1);
X }
X
X if (((Image->red = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
X ((Image->green = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
X ((Image->blue = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL)) {
X printf ("Cannot allocate memory for picture\n");
X exit(1);
X }
X
X for (i = 0 ; i < Image->iheight ; i++) {
X for (j = 0 ; j < nPlanes ; j++)
X if (compression == CMPNONE) {
X for (k = 0 ; k < (Image->iwidth+7)/8 ; k++)
X row_bytes[j][k] = read_byte(f);
X if ((Image->iwidth & 7) != 0)
X read_byte(f);
X }
X else {
X nBytes = 0;
X nBytesRead = 0;
X while (nBytes != (Image->iwidth+7)/8) {
X c = read_byte(f);
X nBytesRead++;
X if ((c >= 0) && (c <= 127))
X for (k = 0 ; k <= c ; k++)
X row_bytes[j][nBytes++] = read_byte(f);
X else if ((c >= 129) && (c <= 255)) {
X count = 257-c;
X c = read_byte(f);
X nBytesRead++;
X for (k = 0 ; k < count ; k++)
X row_bytes[j][nBytes++] = c;
X }
X }
X }
X
X mask = 0x80;
X byte_index = 0;
X for (j = 0 ; j < Image->iwidth ; j++) {
X creg = 0;
X for (k = nPlanes-1 ; k >= 0 ; k--)
X if (row_bytes[k][byte_index] & mask)
X creg = creg*2 + 1;
X else
X creg *= 2;
X
X index = (Image->iheight-i-1)*Image->iwidth + j;
X
X if (viewmodes & HAM) {
X switch (creg >> 4) {
X case 0:
X Previous_Red = Image->red[index] = iff_colour_map[creg].Red;
X Previous_Green = Image->green[index] = iff_colour_map[creg].Green;
X Previous_Blue = Image->blue[index] = iff_colour_map[creg].Blue;
X break;
X
X case 1:
X Image->red[index] = Previous_Red;
X Image->green[index] = Previous_Green;
X Previous_Blue = Image->blue[index] = ((creg & 0xf)<<4) + (creg&0xf);
X break;
X
X case 2:
X Previous_Red = Image->red[index] = ((creg & 0xf)<<4) + (creg&0xf);
X Image->green[index] = Previous_Green;
X Image->blue[index] = Previous_Blue;
X break;
X
X case 3:
X Image->red[index] = Previous_Red;
X Previous_Green = Image->green[index] = ((creg & 0xf)<<4) + (creg&0xf);
X Image->blue[index] = Previous_Blue;
X break;
X }
X }
X else {
X Image->red[index] = iff_colour_map[creg].Red;
X Image->green[index] = iff_colour_map[creg].Green;
X Image->blue[index] = iff_colour_map[creg].Blue;
X }
X
X mask >>= 1;
X if (mask == 0) {
X mask = 0x80;
X byte_index++;
X }
X }
X }
X
X free (row_bytes);
X fclose (f);
X return;
X default:
X for (i = 0 ; i < Chunk_Header.size ; i++)
X if (getc(f) == EOF)
X iff_error();
X break;
X }
X }
X }
END_OF_FILE
if test 10876 -ne `wc -c <'src/iff.c'`; then
echo shar: \"'src/iff.c'\" unpacked with wrong size!
fi
# end of 'src/iff.c'
fi
if test -f 'src/objects.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/objects.c'\"
else
echo shar: Extracting \"'src/objects.c'\" \(11964 characters\)
sed "s/^X//" >'src/objects.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X* objects.c
X*
X* from DKBTrace (c) 1990 David Buck
X*
X* This module implements the methods for objects and composite objects.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file. If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author. It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software. The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them. Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X* David Buck
X* 22C Sonnet Cres.
X* Nepean Ontario
X* Canada, K2H 8W7
X*
X* I can also be reached on the following bulleton boards:
X*
X* ATX (613) 526-4141
X* OMX (613) 731-3419
X* Mystic (613) 731-0088 or (613) 731-6698
X*
X* Fidonet: 1:163/109.9
X* Internet: David_Buck@Carleton.CA
X*
X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X* Lattice BBS (708) 916-1200
X* The Information Exchange BBS (708) 945-5575
X* Stillwaters BBS (708) 403-2826
X*
X*****************************************************************************/
X
X
X#include "frame.h"
X#include "vector.h"
X#include "dkbproto.h"
X
Xextern RAY *VP_Ray;
Xextern long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
X
XMETHODS Composite_Methods =
X { Object_Intersect, All_Composite_Intersections,
X Inside_Composite_Object, NULL,
X Copy_Composite_Object,
X Translate_Composite_Object, Rotate_Composite_Object,
X Scale_Composite_Object, Invert_Composite_Object};
X
XMETHODS Basic_Object_Methods =
X { Object_Intersect, All_Object_Intersections,
X Inside_Basic_Object, NULL,
X Copy_Basic_Object,
X Translate_Basic_Object, Rotate_Basic_Object,
X Scale_Basic_Object, Invert_Basic_Object};
X
X
XINTERSECTION *Object_Intersect (Object, Ray)
X OBJECT *Object;
X RAY *Ray;
X {
X INTERSECTION *Local_Intersection, *Queue_Element;
X PRIOQ *Depth_Queue;
X
X Depth_Queue = pq_new (128);
X
X if ((All_Intersections (Object, Ray, Depth_Queue))
X && ((Queue_Element = pq_get_highest (Depth_Queue)) != NULL))
X {
X Local_Intersection = (INTERSECTION *) malloc(sizeof(INTERSECTION));
X Local_Intersection -> Point = Queue_Element -> Point;
X Local_Intersection -> Shape = Queue_Element -> Shape;
X Local_Intersection -> Depth = Queue_Element -> Depth;
X Local_Intersection -> Object = Queue_Element -> Object;
X pq_free (Depth_Queue);
X return (Local_Intersection);
X }
X else
X {
X pq_free (Depth_Queue);
X return (NULL);
X }
X }
X
Xint All_Composite_Intersections (Object, Ray, Depth_Queue)
X OBJECT *Object;
X RAY *Ray;
X PRIOQ *Depth_Queue;
X {
X register int Intersection_Found;
X SHAPE *Bounding_Shape;
X INTERSECTION *Local_Intersection;
X OBJECT *Local_Object;
X
X for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Bounding_Shape != NULL ;
X Bounding_Shape = Bounding_Shape -> Next_Object) {
X
X Bounding_Region_Tests++;
X if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
X free (Local_Intersection);
X else
X if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
X return (FALSE);
X Bounding_Region_Tests_Succeeded++;
X }
X
X Intersection_Found = FALSE;
X for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X if (All_Intersections (Local_Object, Ray, Depth_Queue))
X Intersection_Found = TRUE;
X
X return (Intersection_Found);
X }
X
Xint All_Object_Intersections (Object, Ray, Depth_Queue)
X OBJECT *Object;
X RAY *Ray;
X PRIOQ *Depth_Queue;
X {
X INTERSECTION *Local_Intersection;
X SHAPE *Bounding_Shape;
X
X for (Bounding_Shape = Object -> Bounding_Shapes ;
X Bounding_Shape != NULL ;
X Bounding_Shape = Bounding_Shape -> Next_Object) {
X
X Bounding_Region_Tests++;
X if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
X free (Local_Intersection);
X else
X if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
X return (FALSE);
X Bounding_Region_Tests_Succeeded++;
X }
X
X All_Intersections ((OBJECT *) Object -> Shape, Ray, Depth_Queue);
X
X if (pq_is_empty (Depth_Queue))
X return (FALSE);
X return (TRUE);
X }
X
X
Xint Inside_Basic_Object (Point, Object)
X VECTOR *Point;
X OBJECT *Object;
X {
X SHAPE *Bounding_Shape;
X
X for (Bounding_Shape = Object -> Bounding_Shapes ;
X Bounding_Shape != NULL ;
X Bounding_Shape = Bounding_Shape -> Next_Object)
X
X if (!Inside (Point, (OBJECT *) Bounding_Shape))
X return (FALSE);
X
X if (Inside (Point, (OBJECT *) Object -> Shape))
X return (TRUE);
X return (FALSE);
X }
X
Xint Inside_Composite_Object (Point, Object)
X VECTOR *Point;
X OBJECT *Object;
X {
X SHAPE *Bounding_Shape;
X OBJECT *Local_Object;
X
X for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Bounding_Shape != NULL ;
X Bounding_Shape = Bounding_Shape -> Next_Object)
X
X if (!Inside (Point, (OBJECT *) Bounding_Shape))
X return (FALSE);
X
X for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X if (Inside (Point, Local_Object))
X return (TRUE);
X
X return (FALSE);
X }
X
Xvoid *Copy_Basic_Object (Object)
X OBJECT *Object;
X {
X SHAPE *Local_Shape, *Copied_Shape;
X OBJECT *New_Object;
X
X New_Object = Get_Object();
X *New_Object = *Object;
X New_Object -> Next_Object = NULL;
X New_Object -> Bounding_Shapes = NULL;
X for (Local_Shape = Object -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object) {
X
X Copied_Shape = (SHAPE *) Copy((OBJECT *) Local_Shape);
X Link ((OBJECT *) Copied_Shape,
X (OBJECT **) &(Copied_Shape -> Next_Object),
X (OBJECT **) &(New_Object -> Bounding_Shapes));
X Copied_Shape -> Parent_Object = Object;
X }
X
X New_Object -> Shape = (SHAPE *) Copy((OBJECT *) Object -> Shape);
X Object -> Shape -> Parent_Object = Object;
X return (New_Object);
X }
X
Xvoid *Copy_Composite_Object (Object)
X OBJECT *Object;
X {
X COMPOSITE *New_Object;
X SHAPE *Local_Shape;
X OBJECT *Local_Object, *Copied_Object;
X
X New_Object = Get_Composite_Object();
X *New_Object = *((COMPOSITE *) Object);
X New_Object -> Next_Object = NULL;
X New_Object -> Objects = NULL;
X for (Local_Object = ((COMPOSITE *) Object) -> Objects;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object) {
X
X Copied_Object = (OBJECT *) Copy(Local_Object);
X Link (Copied_Object,
X &(Copied_Object -> Next_Object),
X &(New_Object -> Objects));
X }
X
X New_Object -> Bounding_Shapes = NULL;
X for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object) {
X
X Copied_Object = (OBJECT *) Copy((OBJECT *) Local_Shape);
X Link (Copied_Object,
X &(Copied_Object -> Next_Object),
X (OBJECT **) &(New_Object -> Bounding_Shapes));
X }
X return (New_Object);
X }
X
Xvoid Translate_Basic_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X SHAPE *Local_Shape;
X
X for (Local_Shape = Object -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Translate ((OBJECT *) Local_Shape, Vector);
X
X Translate ((OBJECT *) Object -> Shape, Vector);
X
X VAdd (Object -> Object_Center, Object -> Object_Center, *Vector);
X }
X
Xvoid Rotate_Basic_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X SHAPE *Local_Shape;
X TRANSFORMATION Transformation;
X
X for (Local_Shape = Object -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Rotate ((OBJECT *) Local_Shape, Vector);
X
X Rotate ((OBJECT *) Object -> Shape, Vector);
X Get_Rotation_Transformation (&Transformation, Vector);
X MTransformVector (&Object->Object_Center,
X &Object->Object_Center, &Transformation);
X }
X
Xvoid Scale_Basic_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X SHAPE *Local_Shape;
X
X for (Local_Shape = Object -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Scale ((OBJECT *) Local_Shape, Vector);
X
X Scale ((OBJECT *) Object -> Shape, Vector);
X
X VEvaluate (Object -> Object_Center, Object -> Object_Center, *Vector);
X }
X
Xvoid Translate_Composite_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X OBJECT *Local_Object;
X SHAPE *Local_Shape;
X
X for (Local_Object = ((COMPOSITE *) Object) -> Objects;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X Translate (Local_Object, Vector);
X
X for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Translate ((OBJECT *) Local_Shape, Vector);
X }
X
Xvoid Rotate_Composite_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X OBJECT *Local_Object;
X SHAPE *Local_Shape;
X
X for (Local_Object = ((COMPOSITE *) Object) -> Objects;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X Rotate (Local_Object, Vector);
X
X for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Rotate ((OBJECT *) Local_Shape, Vector);
X }
X
Xvoid Scale_Composite_Object (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X OBJECT *Local_Object;
X SHAPE *Local_Shape;
X
X for (Local_Object = ((COMPOSITE *) Object) -> Objects;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X Scale (Local_Object, Vector);
X
X for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Scale ((OBJECT *) Local_Shape, Vector);
X }
X
X
Xvoid Invert_Basic_Object (Object)
X OBJECT *Object;
X {
X SHAPE *Local_Shape;
X
X for (Local_Shape = Object -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Invert ((OBJECT *) Local_Shape);
X Invert ((OBJECT *) Object -> Shape);
X }
X
Xvoid Invert_Composite_Object (Object)
X OBJECT *Object;
X {
X OBJECT *Local_Object;
X SHAPE *Local_Shape;
X
X for (Local_Object = ((COMPOSITE *)Object) -> Objects;
X Local_Object != NULL ;
X Local_Object = Local_Object -> Next_Object)
X
X Invert (Local_Object);
X
X for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
X Local_Shape != NULL ;
X Local_Shape = Local_Shape -> Next_Object)
X
X Invert ((OBJECT *) Local_Shape);
X }
END_OF_FILE
if test 11964 -ne `wc -c <'src/objects.c'`; then
echo shar: \"'src/objects.c'\" unpacked with wrong size!
fi
# end of 'src/objects.c'
fi
if test -f 'src/quadrics.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/quadrics.c'\"
else
echo shar: Extracting \"'src/quadrics.c'\" \(11498 characters\)
sed "s/^X//" >'src/quadrics.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X* quadrics.c
X*
X* from DKBTrace (c) 1990 David Buck
X*
X* This module implements the code for the quadric shape primitive.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file. If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author. It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software. The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them. Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X* David Buck
X* 22C Sonnet Cres.
X* Nepean Ontario
X* Canada, K2H 8W7
X*
X* I can also be reached on the following bulleton boards:
X*
X* ATX (613) 526-4141
X* OMX (613) 731-3419
X* Mystic (613) 731-0088 or (613) 731-6698
X*
X* Fidonet: 1:163/109.9
X* Internet: David_Buck@Carleton.CA
X*
X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X* Lattice BBS (708) 916-1200
X* The Information Exchange BBS (708) 945-5575
X* Stillwaters BBS (708) 403-2826
X*
X*****************************************************************************/
X
X
X#include "frame.h"
X#include "vector.h"
X#include "dkbproto.h"
X
XMETHODS Quadric_Methods =
X { Object_Intersect, All_Quadric_Intersections,
X Inside_Quadric, Quadric_Normal,
X Copy_Quadric,
X Translate_Quadric, Rotate_Quadric,
X Scale_Quadric, Invert_Quadric};
X
Xextern RAY *VP_Ray;
Xextern long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
X
Xint All_Quadric_Intersections (Object, Ray, Depth_Queue)
X OBJECT *Object;
X RAY *Ray;
X PRIOQ *Depth_Queue;
X {
X QUADRIC *Shape = (QUADRIC *) Object;
X DBL Depth1, Depth2;
X VECTOR Intersection_Point;
X INTERSECTION Local_Element;
X register int Intersection_Found;
X
X Intersection_Found = FALSE;
X if (Intersect_Quadric (Ray, Shape, &Depth1, &Depth2))
X {
X Local_Element.Depth = Depth1;
X Local_Element.Object = Shape -> Parent_Object;
X VScale (Intersection_Point, Ray -> Direction, Depth1);
X VAdd (Intersection_Point, Intersection_Point, Ray -> Initial);
X Local_Element.Point = Intersection_Point;
X Local_Element.Shape = (SHAPE *)Shape;
X pq_add (Depth_Queue, &Local_Element);
X Intersection_Found = TRUE;
X
X if (Depth2 != Depth1)
X {
X Local_Element.Depth = Depth2;
X Local_Element.Object = Shape -> Parent_Object;
X VScale (Intersection_Point, Ray -> Direction, Depth2);
X VAdd (Intersection_Point, Intersection_Point, Ray -> Initial);
X Local_Element.Point = Intersection_Point;
X Local_Element.Shape = (SHAPE *) Shape;
X pq_add (Depth_Queue, &Local_Element);
X Intersection_Found = TRUE;
X }
X }
X return (Intersection_Found);
X }
X
Xint Intersect_Quadric (Ray, Shape, Depth1, Depth2)
X RAY *Ray;
X QUADRIC *Shape;
X DBL *Depth1, *Depth2;
X {
X register DBL Square_Term, Linear_Term, Constant_Term, Temp_Term;
X register DBL Determinant, Determinant_2, A2, BMinus;
X
X Ray_Quadric_Tests++;
X if (!Ray->Quadric_Constants_Cached)
X Make_Ray(Ray);
X
X if (Shape -> Non_Zero_Square_Term)
X {
X VDot (Square_Term, Shape -> Object_2_Terms, Ray -> Direction_2);
X VDot (Temp_Term, Shape -> Object_Mixed_Terms, Ray -> Mixed_Dir_Dir);
X Square_Term += Temp_Term;
X }
X else
X Square_Term = 0.0;
X
X VDot (Linear_Term, Shape -> Object_2_Terms, Ray -> Initial_Direction);
X Linear_Term *= 2.0;
X VDot (Temp_Term, Shape -> Object_Terms, Ray -> Direction);
X Linear_Term += Temp_Term;
X VDot (Temp_Term, Shape -> Object_Mixed_Terms, Ray -> Mixed_Init_Dir);
X Linear_Term += Temp_Term;
X
X if (Ray == VP_Ray)
X if (!Shape -> Constant_Cached)
X {
X VDot (Constant_Term, Shape -> Object_2_Terms, Ray -> Initial_2);
X VDot (Temp_Term, Shape -> Object_Terms, Ray -> Initial);
X Constant_Term += Temp_Term + Shape -> Object_Constant;
X Shape -> Object_VP_Constant = Constant_Term;
X Shape -> Constant_Cached = TRUE;
X }
X else
X Constant_Term = Shape -> Object_VP_Constant;
X else
X {
X VDot (Constant_Term, Shape -> Object_2_Terms, Ray -> Initial_2);
X VDot (Temp_Term, Shape -> Object_Terms, Ray -> Initial);
X Constant_Term += Temp_Term + Shape -> Object_Constant;
X }
X
X VDot (Temp_Term, Shape -> Object_Mixed_Terms,
X Ray -> Mixed_Initial_Initial);
X Constant_Term += Temp_Term;
X
X if (Square_Term != 0.0)
X {
X /* The equation is quadratic - find its roots */
X
X Determinant_2 = Linear_Term * Linear_Term - 4.0 * Square_Term * Constant_Term;
X
X if (Determinant_2 < 0.0)
X return (FALSE);
X
X Determinant = sqrt (Determinant_2);
X A2 = Square_Term * 2.0;
X BMinus = Linear_Term * -1.0;
X
X *Depth1 = (BMinus + Determinant) / A2;
X *Depth2 = (BMinus - Determinant) / A2;
X }
X else
X {
X /* There are no quadratic terms. Solve the linear equation instead. */
X if (Linear_Term == 0.0)
X return (FALSE);
X
X *Depth1 = Constant_Term * -1.0 / Linear_Term;
X *Depth2 = *Depth1;
X }
X
X if ((*Depth1 < Small_Tolerance) || (*Depth1 > Max_Distance))
X if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance))
X return (FALSE);
X else
X *Depth1 = *Depth2;
X else
X if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance))
X *Depth2 = *Depth1;
X
X Ray_Quadric_Tests_Succeeded++;
X return (TRUE);
X }
X
Xint Inside_Quadric (Point, Object)
X VECTOR *Point;
X OBJECT *Object;
X {
X QUADRIC *Shape = (QUADRIC *) Object;
X VECTOR New_Point;
X register DBL Result, Linear_Term, Square_Term;
X
X VDot (Linear_Term, *Point, Shape -> Object_Terms);
X Result = Linear_Term + Shape -> Object_Constant;
X VSquareTerms (New_Point, *Point);
X VDot (Square_Term, New_Point, Shape -> Object_2_Terms);
X Result += Square_Term;
X Result += Shape -> Object_Mixed_Terms.x * (Point -> x) * (Point -> y)
X + Shape -> Object_Mixed_Terms.y * (Point -> x) * (Point -> z)
X + Shape -> Object_Mixed_Terms.z * (Point -> y) * (Point -> z);
X
X if (Result < Small_Tolerance)
X return (TRUE);
X
X return (FALSE);
X }
X
Xvoid Quadric_Normal (Result, Object, Intersection_Point)
X VECTOR *Result, *Intersection_Point;
X OBJECT *Object;
X {
X QUADRIC *Intersection_Shape = (QUADRIC *) Object;
X VECTOR Derivative_Linear;
X
X VScale (Derivative_Linear, Intersection_Shape -> Object_2_Terms, 2.0);
X VEvaluate (*Result, Derivative_Linear, *Intersection_Point);
X VAdd (*Result, *Result, Intersection_Shape -> Object_Terms);
X
X Result -> x +=
X Intersection_Shape -> Object_Mixed_Terms.x * Intersection_Point -> y +
X Intersection_Shape -> Object_Mixed_Terms.y * Intersection_Point -> z;
X
X
X Result -> y +=
X Intersection_Shape -> Object_Mixed_Terms.x * Intersection_Point -> x +
X Intersection_Shape -> Object_Mixed_Terms.z * Intersection_Point -> z;
X
X Result -> z +=
X Intersection_Shape -> Object_Mixed_Terms.y * Intersection_Point -> x +
X Intersection_Shape -> Object_Mixed_Terms.z * Intersection_Point -> y;
X
X VNormalize (*Result, *Result);
X Perturb_Normal (Result, Intersection_Shape -> Parent_Object,
X Intersection_Point, Result);
X }
X
Xvoid *Copy_Quadric (Object)
X OBJECT *Object;
X {
X QUADRIC *New_Shape;
X
X New_Shape = Get_Quadric_Shape ();
X *New_Shape = *((QUADRIC *) Object);
X New_Shape -> Next_Object = NULL;
X return (New_Shape);
X }
X
Xvoid Transform_Quadric (Shape, Transformation)
X QUADRIC *Shape;
X TRANSFORMATION *Transformation;
X {
X MATRIX Quadric_Matrix, Transform_Transposed;
X
X Quadric_To_Matrix (Shape, (MATRIX *) &Quadric_Matrix[0][0]);
X MTimes ((MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &(Transformation -> inverse[0][0]), (MATRIX *) &Quadric_Matrix[0][0]);
X MTranspose ((MATRIX *) &Transform_Transposed[0][0], (MATRIX *) &(Transformation -> inverse[0][0]));
X MTimes ((MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &Transform_Transposed[0][0]);
X Matrix_To_Quadric ((MATRIX *) &Quadric_Matrix[0][0], Shape);
X }
X
Xvoid Quadric_To_Matrix (Quadric, Matrix)
X QUADRIC *Quadric;
X MATRIX *Matrix;
X {
X MZero (Matrix);
X (*Matrix)[0][0] = Quadric -> Object_2_Terms.x;
X (*Matrix)[1][1] = Quadric -> Object_2_Terms.y;
X (*Matrix)[2][2] = Quadric -> Object_2_Terms.z;
X (*Matrix)[0][1] = Quadric -> Object_Mixed_Terms.x;
X (*Matrix)[0][2] = Quadric -> Object_Mixed_Terms.y;
X (*Matrix)[0][3] = Quadric -> Object_Terms.x;
X (*Matrix)[1][2] = Quadric -> Object_Mixed_Terms.z;
X (*Matrix)[1][3] = Quadric -> Object_Terms.y;
X (*Matrix)[2][3] = Quadric -> Object_Terms.z;
X (*Matrix)[3][3] = Quadric -> Object_Constant;
X }
X
Xvoid Matrix_To_Quadric (Matrix, Quadric)
X MATRIX *Matrix;
X QUADRIC *Quadric;
X {
X Quadric -> Object_2_Terms.x = (*Matrix)[0][0];
X Quadric -> Object_2_Terms.y = (*Matrix)[1][1];
X Quadric -> Object_2_Terms.z = (*Matrix)[2][2];
X Quadric -> Object_Mixed_Terms.x = (*Matrix)[0][1] + (*Matrix)[1][0];
X Quadric -> Object_Mixed_Terms.y = (*Matrix)[0][2] + (*Matrix)[2][0];
X Quadric -> Object_Terms.x = (*Matrix)[0][3] + (*Matrix)[3][0];
X Quadric -> Object_Mixed_Terms.z = (*Matrix)[1][2] + (*Matrix)[2][1];
X Quadric -> Object_Terms.y = (*Matrix)[1][3] + (*Matrix)[3][1];
X Quadric -> Object_Terms.z = (*Matrix)[2][3] + (*Matrix)[3][2];
X Quadric -> Object_Constant = (*Matrix)[3][3];
X }
X
Xvoid Translate_Quadric (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X TRANSFORMATION Transformation;
X
X Get_Translation_Transformation (&Transformation, Vector);
X Transform_Quadric ((QUADRIC *) Object, &Transformation);
X }
X
Xvoid Rotate_Quadric (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X TRANSFORMATION Transformation;
X
X Get_Rotation_Transformation (&Transformation, Vector);
X Transform_Quadric ((QUADRIC *) Object, &Transformation);
X }
X
Xvoid Scale_Quadric (Object, Vector)
X OBJECT *Object;
X VECTOR *Vector;
X {
X TRANSFORMATION Transformation;
X
X Get_Scaling_Transformation (&Transformation, Vector);
X Transform_Quadric ((QUADRIC *) Object, &Transformation);
X }
X
Xvoid Invert_Quadric (Object)
X OBJECT *Object;
X {
X QUADRIC *Shape = (QUADRIC *) Object;
X
X VScale (Shape -> Object_2_Terms, Shape -> Object_2_Terms, -1.0);
X VScale (Shape -> Object_Mixed_Terms, Shape -> Object_Mixed_Terms, -1.0);
X VScale (Shape -> Object_Terms, Shape -> Object_Terms, -1.0);
X Shape -> Object_Constant *= -1.0;
X }
END_OF_FILE
if test 11498 -ne `wc -c <'src/quadrics.c'`; then
echo shar: \"'src/quadrics.c'\" unpacked with wrong size!
fi
# end of 'src/quadrics.c'
fi
echo shar: End of archive 4 \(of 10\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 10 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.