home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d130
/
evo.lha
/
Evo
/
evo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-03-13
|
21KB
|
721 lines
#include "INCLUDE:Lattice/math.h"
#include "INCLUDE:Lattice/stdio.h"
#include "INCLUDE:exec/types.h"
#include "INCLUDE:graphics/gfx.h"
#include "INCLUDE:graphics/gfxmacros.h"
#include "INCLUDE:exec/exec.h"
#include "INCLUDE:exec/execbase.h"
#include "INCLUDE:graphics/view.h"
#include "INCLUDE:graphics/gfxbase.h"
#include "INCLUDE:exec/libraries.h"
#include "INCLUDE:intuition/intuition.h"
#include "INCLUDE:graphics/text.h"
struct NewScreen ns;
struct NewWindow nw;
struct Screen *evo_screen;
struct Window *evo_window, *map_window, *text_window;
struct RastPort *rp, *rp2;
struct ViewPort *vp;
struct IntuiMessage *message;
struct TextAttr Ruby_Eight;
struct TextFont *fontptr;
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct Library *DiskfontBase;
SHORT hominid;
SHORT hominid_index[621];
int i, j, x, y, oldx, class, code, rc, color, parity;
int delta_t, delta_x, delta_y, s, fossil_index;
int point, selected_box;
BOOL button_is_down, first_pass;
UBYTE profile[ 621 ][ 52 ][ 2 ];
int SetUpEvographics(), DrawMap(), DisplayText();
#include "evo_species.include"
#include "evo_data.include"
#include "evo_africa.include"
#include "evo_text.include"
/*---------------------------------------*/
/* */
/* // Evo // */
/* */
/* A human evolution demonstration */
/* program for the Amiga */
/* */
/* Steve Bonner */
/* August 1987 */
/* */
/*---------------------------------------*/
main()
{
register int k;
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
if( (GfxBase == NULL) || (IntuitionBase == NULL)) exit();
DiskfontBase = OpenLibrary("diskfont.library",0);
if ( DiskfontBase == NULL ) exit();
SetUpEvographics();
SetDrMd( rp, JAM2 );
SetAPen( rp, 2 );
RectFill( rp, 45, 20, 295, 120 );
Move( rp, 110, 55 );
SetAPen( rp, 7 );
SetBPen( rp, 2 );
Text( rp, "(please wait)", 13 );
SetAPen( rp, 2 );
SetBPen( rp, 0 );
Move( rp, 20, 140 );
Draw( rp, 620, 140 );
for ( i = 0; i <= 20; i++) {
Move( rp, gradation[i], 138 );
Draw( rp, gradation[i], 142 ); }
Move( rp, 9, 137 );
Text( rp,
"20 10 5 4 3 2 1 ", 55 );
Move( rp, 9, 152 );
Text( rp,
" Miocene Pliocene Pleistocene", 55 );
Move( rp, 325, 45 ) ;
Text( rp, "Genus ", 12 );
Move( rp, 325, 60 ) ;
Text( rp, "Species ", 12 );
Move( rp, 325, 75 ) ;
Text( rp, "Subspecies ", 12 );
Move( rp, 325, 90 ) ;
Text( rp, "Mill yrs ago", 12 );
Move( rp, 435, 45 );
Text( rp, ":", 1 );
Move( rp, 435, 60 );
Text( rp, ":", 1 );
Move( rp, 435, 75 );
Text( rp, ":", 1 );
Move( rp, 435, 90 );
Text( rp, ":", 1 );
/* Draw the boxes to surround user options: */
for ( k = 0; k < 5; k++) {
SetAPen( rp, 3 );
RectFill( rp, 20 + k * 122, 172, 132 + k * 122, 192 );
SetAPen( rp, 6 );
Move( rp, 20 + k * 122 , 172 );
Draw( rp, 132 + k * 122 , 172 );
Draw( rp, 132 + k * 122 , 192 );
Draw( rp, 20 + k * 122 , 192 );
Draw( rp, 20 + k * 122 , 172 ); }
SetDrMd( rp, JAM1 );
Move( rp, 20, 185 );
/* Here are the various options: */
Text( rp,
" Help Text Map Glossary Notes",
61 );
SetAPen( rp, 2 );
SetDrMd( rp, JAM2 );
x = 0;
y = 1;
/* The cranium for each hominid species consists of 52 points */
/* which define its outline. Here we are copying the outlines */
/* of the nine known hominids into our working array, 'profile' */
for ( i = 0; i <= 51; i++) {
j = 2*i;
k = j+1;
profile[ 20 ][ i ][ x ] = proconsul_profile[ j ];
profile[ 20 ][ i ][ y ] = proconsul_profile[ k ];
profile[ 147 ][ i ][ x ] = kenyapith_profile[ j ];
profile[ 147 ][ i ][ y ] = kenyapith_profile[ k ];
profile[ 333 ][ i ][ x ] = afarensis_profile[ j ];
profile[ 333 ][ i ][ y ] = afarensis_profile[ k ];
profile[ 360 ][ i ][ x ] = africanus_profile[ j ];
profile[ 360 ][ i ][ y ] = africanus_profile[ k ];
profile[ 403 ][ i ][ x ] = habilis_profile [ j ];
profile[ 403 ][ i ][ y ] = habilis_profile [ k ];
profile[ 439 ][ i ][ x ] = erectus_profile [ j ];
profile[ 439 ][ i ][ y ] = erectus_profile [ k ];
profile[ 554 ][ i ][ x ] = esapiens_profile [ j ];
profile[ 554 ][ i ][ y ] = esapiens_profile [ k ];
profile[ 611 ][ i ][ x ] = neander_profile [ j ];
profile[ 611 ][ i ][ y ] = neander_profile [ k ];
profile[ 620 ][ i ][ x ] = msapiens_profile [ j ];
profile[ 620 ][ i ][ y ] = msapiens_profile [ k ]; }
/* Interpolate between known hominid forms: */
for ( i = PROCONSUL; i <= NEANDER; i++) {
delta_t = fossil_dates[i+1] - fossil_dates[i];
fossil_index = fossil_dates[i];
Forbid();
/* Now consider each point along the profile: */
for ( j = 0; j <= 51; j++ ) {
delta_x = profile[ fossil_dates[i+1] ][ j ][ x ] -
profile[ fossil_index ][ j ][ x ] ;
delta_y = profile[ fossil_dates[i+1] ][ j ][ y ] -
profile[ fossil_index ][ j ][ y ] ;
s = 1;
/* Here we do the linear interpolation. */
/* (I interpolate on the logarithmic scale, since it's easier.) */
for ( k = fossil_dates[i]+1; k < fossil_dates[i+1]; k++) {
profile[ k ][ j ][ x ] = profile[ fossil_index ][ j ][ x ] +
s * delta_x / delta_t;
profile[ k ][ j ][ y ] = profile[ fossil_index ][ j ][ y ] +
s * delta_y / delta_t;
s++;
}
} /* j */
/* Let's give our disk drive a chance to catch up: */
Permit();
} /* i */
button_is_down = FALSE;
oldx = 403;
SetAPen( rp, 1 );
WritePixel( rp, oldx, 140 );
hominid = 4;
Move( rp, 460, 45 );
Text( rp, genera[ hominid ], 18 );
Move( rp, 460, 60 );
Text( rp, species[ hominid ], 18 );
Move( rp, 460, 90 );
Text( rp, yearstring[oldx], 6 );
/* Hominid_divisions allows us to rapidly map an x-coordinate */
/* into its corresponding hominid form (an integer from 0 to 8) */
hominid = 8;
for (i = 620; i >= 20; i--) {
if ( i < hominid_divisions[ hominid ] ) hominid--;
hominid_index[i] = hominid; }
color = 8;
hominid = 4;
first_pass = TRUE;
Forbid();
while ( 1 == 1) {
if (first_pass == FALSE ) {
WaitPort( evo_window -> UserPort );
message = GetMsg( evo_window -> UserPort );
class = message -> Class;
code = message -> Code;
x = message -> MouseX;
y = message -> MouseY;
ReplyMsg( message ); }
else {
class = 0;
code = SELECTUP;
x = oldx;
y = 140;
first_pass = FALSE; }
if ( class == CLOSEWINDOW ) {
CloseWindow( evo_window );
CloseScreen( evo_screen );
exit(); }
if ( code == SELECTDOWN ) {
point = ReadPixel( rp, x, y );
/* Is our current pixel a 'user-option' color?. . . */
if ( (point == 3) || (point == 6) ) {
selected_box = (x - 10)/122;
if (selected_box == 2)
DrawMap();
else
DisplayText();
goto NoSkull; }
button_is_down = TRUE;
color = 8; }
if ( code == SELECTUP ) button_is_down = FALSE;
if ( (button_is_down) || (code == SELECTUP) ) {
if ((x >= 20) && (x <= 620)) {
SetAPen( rp, 2 );
WritePixel( rp, oldx, 140 );
SetAPen( rp, 1 );
WritePixel( rp, x, 140 );
oldx = x;
/* If the species has changed, update the labels: */
if ( hominid != hominid_index[x] ) {
hominid = hominid_index[x];
Move( rp, 460, 45 );
Text( rp, genera[ hominid ], 18 );
Move( rp, 460, 60 );
Text( rp, species[ hominid ], 18 );
Move( rp, 460, 75 );
Text( rp, subspecies[ hominid ], 18 ); }
Move( rp, 460, 90 );
Text( rp, yearstring[x], 6 );
if ( code == SELECTUP ) {
color = 1;
SetAPen( rp, 2 );
RectFill( rp, 45, 20, 295, 120 ); }
else {
color++;
color%=16;
if (color < 8) color += 8; }
parity = x % 2;
/* we cheat a little to speed things up: */
if ((code != SELECTUP) && (code != SELECTDOWN) && (parity == 1)) {
goto FastForward; }
SetAPen( rp, color );
Move( rp, profile[ x ][ 0 ][ 0 ], profile[ x ][ 0 ][ 1 ] );
/* Draw the outside of the cranium: */
Disable();
/* OK, let's see if it can keep up. . . */
for ( k = 1; k < 27; k++ ) {
Draw( rp, profile[x][k][0], profile[x][k][1] ); }
Enable();
Draw( rp, profile[x][0][0], profile[x][0][1] );
/* Now for the lower cheekbone */
Move( rp, profile[x][27][0], profile[x][27][1] );
for ( k=28; k < 30; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
/* Now the upper cheekbone: */
Move( rp, profile[x][30][0], profile[x][30][1] );
for ( k=31; k < 39; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
/* Now draw around the eye: */
Move( rp, profile[x][39][0], profile[x][39][1] );
for ( k=40; k < 47; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
Draw( rp, profile[x][39][0], profile[x][39][1] );
/* Now draw around the ear: */
Move( rp, profile[x][47][0], profile[x][47][1] );
for ( k=48; k < 52; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
Draw( rp, profile[x][47][0], profile[x][47][1] );
FastForward:
} /* x in range 20..620 */
} /* Button is down */
NoSkull:
} /* While End */
} /* main */
/*--------------------------------------------*/
SetUpEvographics()
{
int font_avail;
BOOL response;
struct IntuiText nofont, stop;
/* Use ruby font in 80-column size: */
Ruby_Eight.ta_Name = "ruby.font";
Ruby_Eight.ta_YSize = 8;
Ruby_Eight.ta_Style = 0;
Ruby_Eight.ta_Flags = 0;
font_avail = OpenDiskFont(&Ruby_Eight);
/* If the ruby font is not available, display a requester and exit: */
if ( font_avail == FALSE ) {
nofont.FrontPen = 3;
nofont.BackPen = 2;
nofont.DrawMode = JAM1;
nofont.LeftEdge = 10;
nofont.TopEdge = 5;
nofont.ITextFont = NULL;
nofont.IText = "Ruby font not in font directory.\0";
nofont.NextText = NULL;
stop.FrontPen = 2;
stop.BackPen = 3;
stop.DrawMode = JAM1;
stop.LeftEdge = 4;
stop.TopEdge = 3;
stop.ITextFont = NULL;
stop.IText = "exit\0";
stop.NextText = NULL;
response = AutoRequest(NULL, &nofont, NULL, &stop, 0,0,420,60);
exit(); }
/* Define properties new screen is to have: */
ns.LeftEdge = 0;
ns.TopEdge = 0;
ns.Width = 640;
ns.Height = 200;
ns.Depth = 4;
ns.DetailPen = 1;
ns.BlockPen = 2;
ns.ViewModes = HIRES;
ns.Type = CUSTOMSCREEN;
ns.Font = &Ruby_Eight;
ns.DefaultTitle = " \0";
ns.Gadgets = NULL;
ns.CustomBitMap = NULL;
evo_screen = OpenScreen( &ns );
if ( evo_screen == NULL ) exit();
/* Describe new window: */
nw.LeftEdge = 0;
nw.TopEdge = 0;
nw.Width = 640;
nw.Height = 200;
nw.DetailPen = -1;
nw.BlockPen = -1;
nw.IDCMPFlags = CLOSEWINDOW | MOUSEBUTTONS | MOUSEMOVE;
nw.Type = CUSTOMSCREEN;
nw.Flags = WINDOWCLOSE | SMART_REFRESH | ACTIVATE |
NOCAREREFRESH | REPORTMOUSE ;
nw.FirstGadget = NULL;
nw.CheckMark = NULL;
nw.Screen = evo_screen;
nw.Title = " Evo ";
nw.BitMap = NULL;
nw.MinWidth = 0;
nw.MinHeight = 0;
nw.MaxWidth = 0;
nw.MaxHeight = 0;
evo_window = OpenWindow( &nw );
if (evo_window == NULL) exit();
WindowToFront(evo_window);
rp = evo_window -> RPort;
vp = &evo_screen -> ViewPort;
SetRGB4( vp, 0, 7, 2, 3 ); /* plum */
SetRGB4( vp, 1, 10, 10, 7 ); /* brown */
SetRGB4( vp, 2, 0, 0, 0 ); /* black */
SetRGB4( vp, 3, 10, 5, 0 ); /* brown */
SetRGB4( vp, 4, 13, 13, 0 ); /* yellow */
SetRGB4( vp, 5, 11, 7, 0 ); /* tan */
SetRGB4( vp, 6, 0, 0, 0 ); /* black */
SetRGB4( vp, 7, 0, 10, 0 ); /* green */
/* The colors used to slide from one hominid into another: */
SetRGB4( vp, 8, 15, 0, 1 );
SetRGB4( vp, 9, 14, 0, 2 );
SetRGB4( vp, 10, 13, 0, 3 );
SetRGB4( vp, 11, 12, 0, 4 );
SetRGB4( vp, 12, 11, 0, 5 );
SetRGB4( vp, 13, 10, 0, 6 );
SetRGB4( vp, 14, 9, 0, 7 );
SetRGB4( vp, 15, 8, 0, 8 );
}
/*-------------------------------------------------*/
DrawMap()
{
PLANEPTR temp_bitplane;
struct TmpRas temp_rast;
struct IntuiMessage *message2;
int num_ticks, blue_level, b;
message = 5;
/* Dispose of any extraneous messages waiting at our old port: */
while ( message != NULL ) {
message = GetMsg( evo_window -> UserPort );
message2 = message;
if ( message2 != NULL ) ReplyMsg( message2 ); }
/* Describe map window: */
nw.IDCMPFlags = CLOSEWINDOW | INTUITICKS;
nw.Flags = WINDOWCLOSE | ACTIVATE;
nw.Title = " Map : African Hominid Fossil Sites ";
for( i = 0; i < 8; i++) SetRGB4( vp, 8+i, 0, 0, i+6 );
map_window = OpenWindow( &nw );
if (map_window == NULL) exit();
rp2 = map_window -> RPort;
temp_bitplane = AllocRaster(640,200);
if (temp_bitplane == 0) exit();
rp2 -> TmpRas = InitTmpRas( &temp_rast, temp_bitplane, RASSIZE(640,200));
color = 8;
for ( i = 10; i < 200; i+= 2) {
color ++;
color %= 8;
color += 8;
SetAPen( rp2, color );
Move( rp2, 1, i );
Draw( rp2, 638, i );
Move( rp2, 1, i+1 );
Draw( rp2, 638, i+1 ); }
SetAPen( rp2, 2 );
Move( rp2, africa[0], africa[1] + 12 );
for (i = 2; i < sizeof(africa) / 2; i+=2) {
Draw( rp2, africa[i], africa[i+1] + 12 ); }
Draw( rp2, africa[0], africa[1] + 12 );
for( i = 0; i < 142; i+=2) {
features[ i ] = feature[ i ];
features[i+1] = feature[i+1] + 12; }
Move( rp2, features[0], features[1] );
for (i = 0; i < 5; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[0], features[1] );
Move( rp2, features[6], features[7] );
for (i = 6; i < 13; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[6], features[7] );
Move( rp2, features[14], features[15] );
for (i = 14; i < 21; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[14], features[15] );
Move( rp2, features[22], features[23] );
for (i = 22; i < 39; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[22], features[23] );
Move( rp2, features[40], features[41] );
for (i = 40; i < 45; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[40], features[41] );
Move( rp2, features[46], features[47] );
for (i = 46; i < 55; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[46], features[47] );
Move( rp2, features[56], features[57] );
for (i = 56; i < 63; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[56], features[57] );
Move( rp2, features[64], features[65] );
for (i = 64; i < 73; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[64], features[65] );
Move( rp2, features[74], features[75] );
for (i = 74; i < 81; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[74], features[75] );
Move( rp2, features[82], features[83] );
for (i = 82; i < 109; i+=2) Draw(rp2,features[i],features[i+1]);
Draw( rp2, features[82], features[83] );
SetAPen( rp2, 5 );
SetOPen( rp2, 2 );
Flood( rp2, 0, 320, 100 );
/* Plot the fossil sites: */
SetAPen( rp2, 2 );
for (i = 110; i < 141; i+=2) {
WritePixel( rp2,features[i], features[i+1]);
WritePixel( rp2,features[i]+1,features[i+1]); }
SetDrMd( rp2, JAM1 );
SetAPen( rp2, 4 );
for (i = 0; i < 16; i++) {
Move( rp2, 510, 30 + i*10 );
Text( rp2, fossil_sites[i], 13 ); }
SetAPen( rp2, 2 );
for ( i = 0; i < 16; i++ ) {
Move( rp2, features[110 + 2*i] + 4, features[111 + 2*i] );
Draw( rp2, 505, 26 + i*10 ); }
class = 0;
num_ticks = 0;
blue_level = 6;
while ( class != CLOSEWINDOW ) {
WaitPort( map_window -> UserPort );
message2 = GetMsg( map_window -> UserPort );
class = message2 -> Class;
ReplyMsg( message2 );
if ( class == INTUITICKS ) {
/* Every fourth tick, cycle the background colors: */
if ( num_ticks++ > 3 ) {
num_ticks = 0;
blue_level ++;
if (blue_level > 13) blue_level = 7;
for( i = 0; i < 8; i++) {
b = blue_level + i;
b %= 8;
b += 6;
SetRGB4( vp, 8+i, 0, 0, b ); }
}
}
}
CloseWindow( map_window );
/* Restore colors to those used by the main Evo window: */
SetRGB4( vp, 8, 15, 0, 1 );
SetRGB4( vp, 9, 14, 0, 2 );
SetRGB4( vp, 10, 13, 0, 3 );
SetRGB4( vp, 11, 12, 0, 4 );
SetRGB4( vp, 12, 11, 0, 5 );
SetRGB4( vp, 13, 10, 0, 6 );
SetRGB4( vp, 14, 9, 0, 7 );
SetRGB4( vp, 15, 8, 0, 8 );
}
/*----------------------------------------------*/
DisplayText()
{
struct IntuiMessage *message2;
char *text_ptr, delimiter;
int red, green, blue, intensity;
ULONG seconds, micros;
message = 5;
/* Dispose of any extraneous messages waiting at our old port: */
while ( message != NULL ) {
message = GetMsg( evo_window -> UserPort );
message2 = message;
if ( message2 != NULL ) ReplyMsg( message2 ); }
/* Describe map window: */
nw.IDCMPFlags = CLOSEWINDOW;
nw.Flags = WINDOWCLOSE | ACTIVATE;
if ( selected_box == 1 )
nw.Title = hominid_title[ hominid ];
else
nw.Title = window_title[ selected_box ];
text_window = OpenWindow( &nw );
if (text_window == NULL) exit();
rp2 = text_window -> RPort;
CurrentTime(&seconds, µs);
srand(micros);
red = rand() % 15;
green = rand() % 12;
blue = rand() % 9;
intensity = red + green + blue;
if (intensity < 26) {
red +=2;
green +=2;
if ( red > 15 ) red = 15;
if ( green > 15 ) green = 15; }
SetRGB4( vp, 0, red, green, blue );
SetDrMd( rp2, JAM1 );
SetAPen( rp2, 2 );
i = 0;
delimiter = ' ';
while ( delimiter != '?' ) {
if ( selected_box == 1 ) {
/* We'll pretend there are just 3 for now: */
if ( hominid == PROCONSUL ) text_ptr = proconsul_text[i];
if ( hominid == KENYAPITH ) text_ptr = kenyapith_text[i];
if ( hominid == AFARENSIS ) text_ptr = afarensis_text[i];
if ( hominid == AFRICANUS ) text_ptr = africanus_text[i];
if ( hominid == HABILIS ) text_ptr = habilis_text[i];
if ( hominid == ERECTUS ) text_ptr = erectus_text[i];
if ( hominid == ESAPIENS ) text_ptr = esapiens_text[i];
if ( hominid == NEANDER ) text_ptr = neander_text[i];
if ( hominid == MSAPIENS ) text_ptr = msapiens_text[i];
}
else {
if (selected_box == 0) text_ptr = help_text[i];
if (selected_box == 3) text_ptr = glossary_text[i];
if (selected_box == 4) text_ptr = notes_text[i]; }
delimiter = *text_ptr;
if ( delimiter != '?' ) {
Move( rp2, 40, 18 + 10 * i );
Text( rp2, text_ptr, 56 );
i++; }
}
WaitPort( text_window -> UserPort );
message2 = GetMsg( text_window -> UserPort );
ReplyMsg( message2 );
SetRGB4( vp, 0, 7, 2, 3 ); /* plum */
/* The only message we were expecting was the window closure: */
CloseWindow( text_window );
}