
/* Program to simulate the trench from Star Wars */
/* Written 7/12/85 by Steve Hawley in MegaMax C for macintosh */

/* 
 * revised by Steve Tynor 7/23/85 for DR C on the ATARI ST
 */

#include <obdefs.h>
#include <define.h>
#include <gemdefs.h>
#include <osbind.h>

#define WI_KIND (NAME)

#define NO_WINDOW (-1)

#define MIN_WIDTH  (2*gl_wbox)
#define MIN_HEIGHT (3*gl_hbox)

extern int gl_apid;

/*********************************************************************/
/* GLOBAL VARIABLES					   	     */
/*********************************************************************/

int	gl_hchar;
int	gl_wchar;
int	gl_wbox;
int	gl_hbox;	/* system sizes */

int 	phys_handle;	/* physical workstation handle */
int 	handle;		/* virtual workstation handle */
int	wi_handle;	/* window handle */
int	top_window;	/* handle of topped window */

int	xdesk,ydesk,hdesk,wdesk;
int	xold,yold,hold,wold;
int	xwork,ywork,hwork,wwork;	/* desktop and work areas */

int	msgbuff[8];	/* event message buffer */
int	keycode;	/* keycode returned by event-keyboard */
int	mx,my;		/* mouse x and y pos. */
int	butdown;	/* button state tested for, UP/DOWN */
int	ret;		/* dummy return variable */

int	hidden;		/* current state of cursor */

int	fulled;		/* current state of window */

int	contrl[12];
int	intin[128];
int	ptsin[128];
int	intout[128];
int	ptsout[128];	/* storage wasted for idiotic bindings */

int work_in[11];	/* Input to GSX parameter array */
int work_out[57];	/* Output from GSX parameter array */
int pxyarray[10];	/* input point array */
int points[20];

/****************************************************************/
/*  GSX UTILITY ROUTINES.					*/
/****************************************************************/

hide_mouse()
{
	if(! hidden){
		graf_mouse(M_OFF,0x0L);
		hidden=TRUE;
	}
}

show_mouse()
{
	if(hidden){
		graf_mouse(M_ON,0x0L);
		hidden=FALSE;
	}
}

/****************************************************************/
/* open virtual workstation					*/
/****************************************************************/
open_vwork()
{
        int i;

	for(i=0;i<10;work_in[i++]=1);
	work_in[10]=2;
	handle=phys_handle;
	v_opnvwk(work_in,&handle,work_out);
        
        set_clip(1, 40, 638, 398);
}

/****************************************************************/
/* set clipping rectangle					*/
/****************************************************************/
set_clip(x,y,w,h)
int x,y,w,h;
{
int clip[4];
	clip[0]=x;
	clip[1]=y;
	clip[2]=x+w;
	clip[3]=y+h;
	vs_clip(handle,1,clip);
}

/****************************************************************/
/* open window							*/
/****************************************************************/
open_window()
{
	wi_handle=wind_create(WI_KIND,xdesk,ydesk,wdesk,hdesk);
	wind_set(wi_handle, WF_NAME," ST Trench ",0,0);
	graf_growbox(xdesk+wdesk/2,ydesk+hdesk/2,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk);
	wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
	wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);

        /* blank out the window */
        white_out(0, 34, 639, 399);
}

/**********************************************************************/
white_out (xx1, yy1, xx2, yy2)   
int xx1, yy1, xx2, yy2;

{
        int a[4];
        int d;

        a[0] = xx1;
        a[1] = yy1;
        a[2] = xx2;
        a[3] = yy2;
        d = vsf_interior (handle, 2);  /* fill solid         */
        d = vsf_style (handle, 8);     /* plain black        */
        vr_recfl (handle, a);          /* draw the rectangle */
}


/**********************************************************************/
drawlines(offx, offy, start) /* draws lines to give illusion of depth */
	int offx, offy, start;
{
	int x1 = -300, x2 = -100, y1 = -100;
	int z;

/* start is the phase (from 0 to 3), The lines are projected by */
/* the formulae x' = x/z; y' = y/z. offx and offy are offsets for*/
/* viewpoint changes */
	
	for (z = 50 - start; z > 0; z -= 4)
	{
		points[0] = 320 + (x2 - offx)/z;  /* left vertical */
		points[1] = 200 + (y1 - offy)/z;
		points[2] = 320 + (x2 - offx)/z;
		points[3] = 200 + (-y1 - offy)/z;
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + (-x2 - offx)/z; /* right vertical */
		points[1] = 200 + ( y1 - offy)/z;
		points[2] = 320 + (-x2 - offx)/z;
		points[3] = 200 + (-y1 - offy)/z;
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + ( x2 - offx)/z; /* center horizontal */
		points[1] = 200 + (-y1 - offy)/z;
		points[2] = 320 + (-x2 - offx)/z;
		points[3] = 200 + (-y1 - offy)/z;
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + (-x1 - offx)/z; /* right horizontal */
		points[1] = 200 + ( y1 - offy)/z;
		points[2] = 320 + (-x2 - offx)/z;
		points[3] = 200 + ( y1 - offy)/z;
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + ( x1 - offx)/z; /* left horizontal */
		points[1] = 200 + ( y1 - offy)/z;
		points[2] = 320 + ( x2 - offx)/z;
		points[3] = 200 + ( y1 - offy)/z;
		v_pline (handle, 2, points);  /* GEM draw line */
	}
}

setup(offx, offy) /* draws the frame of the trench */
int offx, offy;
/* offx and offy again represent the viewpoint offsets, and it is */
/* projected using the same formulae as before */

{

	int x1 = -300, x2 = -100, y1 = -100;

/* indented code draws the front horizontal lines (as would be drawn by
 * drawlines()
 */
		points[0] = 320 + (x2 - offx);  /* left vertical */
		points[1] = 200 + (y1 - offy);
		points[2] = 320 + (x2 - offx);
		points[3] = 200 + (-y1 - offy);
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + (-x2 - offx); /* right vertical */
		points[1] = 200 + ( y1 - offy);
		points[2] = 320 + (-x2 - offx);
		points[3] = 200 + (-y1 - offy);
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + ( x2 - offx); /* center horizontal */
		points[1] = 200 + (-y1 - offy);
		points[2] = 320 + (-x2 - offx);
		points[3] = 200 + (-y1 - offy);
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + (-x1 - offx); /* right horizontal */
		points[1] = 200 + ( y1 - offy);
		points[2] = 320 + (-x2 - offx);
		points[3] = 200 + ( y1 - offy);
		v_pline (handle, 2, points);  /* GEM draw line */

		points[0] = 320 + ( x1 - offx); /* left horizontal */
		points[1] = 200 + ( y1 - offy);
		points[2] = 320 + ( x2 - offx);
		points[3] = 200 + ( y1 - offy);
		v_pline (handle, 2, points);  /* GEM draw line */

       	
        points[0] = 320 + (x2 - offx);
	points[1] = 200 + (y1 - offy);
	points[2] = 320 + (x2 - offx)/50;
	points[3] = 200 + (y1 - offy)/50;
	points[4] = 320 + (x1 - offx)/50;
	points[5] = 200 + (y1 - offy)/50;
	points[6] = 320 + (x1 - offx);
	points[7] = 200 + (y1 - offy);
	v_pline (handle, 4, points);  /* GEM draw polyline */

        points[0] = 320 + (x2 - offx);
	points[1] = 200 + (-y1 - offy);
	points[2] = 320 + (x2 - offx)/50;
	points[3] = 200 + (-y1 - offy)/50;
	v_pline (handle, 2, points);  /* GEM draw polyline */

        points[0] = 320 + (-x2 - offx);
	points[1] = 200 + (y1 - offy);
	points[2] = 320 + (-x2 - offx)/50;
	points[3] = 200 + (y1 - offy)/50;
	points[4] = 320 + (-x1 - offx)/50;
	points[5] = 200 + (y1 - offy)/50;
	points[6] = 320 + (-x1 - offx);
	points[7] = 200 + (y1 - offy);
	v_pline (handle, 4, points);  /* GEM draw polyline */

        points[0] = 320 + (-x2 - offx);
	points[1] = 200 + (-y1 - offy);
	points[2] = 320 + (-x2 - offx)/50;
	points[3] = 200 + (-y1 - offy)/50;
	v_pline (handle, 2, points);  /* GEM draw polyline */
}

main()
{
/* the objects are animated by using exclusive-or drawing. this way, the   */
/* same routine to draw can be used to erase, and the new image can be     */
/* drawn before the old image is erased to help eliminate flicker. Thus    */
/* the the program needs two copies of the offset parameters, one for the  */
/* new and one for the old.                                                */

	int offxo=320,offxn=320,offyo=200,offyn=200;
	int mouse_x=320, mouse_y=200;
        int button=0;
        int keybd=0;   
        int wlines=0;
	int work_in[11], work_out[57], i, dummy_var;
   

	appl_init();
	phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
	wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);

        hide_mouse();
	open_vwork();
        open_window();

        graf_mouse(ARROW,0x0L);
        show_mouse();

        dummy_var = vswr_mode (handle, 3);   /* set XOR writing mode */

	hidden=FALSE;
	fulled=FALSE;
	butdown=TRUE;

	setup(offxn,offyn); /*draw initial setup*/
	drawlines(offxn, offyn, wlines); /*draw initial depth lines */
        
        show_mouse();

	while(keybd == 0)       /*repeat until button is down*/
	{
/*                for (i=1 ; i < 300 ; i++ );  (* delay */

		offxo = offxn;   /* Put new offsets in old variables */
		offyo = offyn;
		dummy_var = graf_mkstate (&mouse_x, &mouse_y,
				  &button, &keybd);   /* GEM get mouse state*/
		if ((mouse_x - 320) != offxo)/*if the horizontal has changed*/
		   offxn =  mouse_x - 320;    /* store it in the new offset */
		if ((mouse_y - 320) != offyo)         /* ditto for vertical */
		   offyn =  mouse_y-200;
		if ( (offxo != offxn) || (offyo != offyn))
			  /* if the old offset differs from the new, update */
		{
			setup(offxn, offyn);               /*draw new setup */
			setup(offxo, offyo);                    /*erase old */
		}

		drawlines(offxo, offyo, wlines); /* erase the vertical lines */
		wlines++; /* increment wlines */
		if (wlines > 3) wlines = 0; /* reset wlines if too big */
		drawlines(offxn, offyn, wlines); /* draw new set of lines */
	}

        wind_close(wi_handle);
        graf_shrinkbox(xwork+wwork/2, ywork+hwork/2,
                       gl_wbox, gl_hbox,
                       xwork, ywork, wwork, hwork);
        wind_delete(wi_handle);
        v_clsvwk(handle);
        appl_exit();
}

þmÞ9  EÃH€0@"|  F0˜ H€0@ÑÈÑÈÑü  EÈ#Ð  Cv9  EÂH€Ð| Áü Ð¼  B2 @1|  
9  EÄ