/*
**	$VER: VirginDemo.c 1.1 (02-Feb-1998)
**
**	This is an example program for cgx3dvirgin.library
**
**      Written by Frank Mariak
**  This f***ed triangle clipping done by Michal Bartczak
**
**	Copyright © 1996-1998 by phase5 digital products
**      All Rights reserved.
**
*/

#define ADDING 3.14/64

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include <cybergraphics/cybergraphics.h>
#include <cybergraphics/cgx3dvirgin.h>
#include <dos/dos.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/lowlevel.h>

#include <proto/cybergraphics.h>
#include <proto/cgx3dvirgin.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/lowlevel.h>

#define DEMO2

#ifndef DEMO1 // textured demo with z-buffering
#ifndef DEMO2 // textured demo without z-buffering
#ifndef DEMO3 // lit textured demo without z-buffering
#ifndef DEMO4 // goroud shaded demo without z-buffering
        You need to specify at least one of the above defines!
#else
#ifdef LUTMODE
        Demo4 does not work in LUTMODE !
#endif
#endif
#else
#ifdef LUTMODE
        Demo3 does not work in LUTMODE !
#endif
#endif
#endif
#endif


#define DISPLAYWIDTH    640
#define DISPLAYHEIGHT   480
#define WINX	DISPLAYWIDTH
#define WINY	DISPLAYHEIGHT
#define FOCUS 400.0 // 400.0

#define Up      0x4c
#define Left    0x4f
#define Down    0x4d
#define Right   0x4e

#define AUp     0x3e
#define ALeft   0x2d
#define ADown   0x1e
#define ARight  0x2f
#define AAxUp   0x1d
#define AAxDown 0x3f
#define Plus    0x5e
#define Minus   0x4a
#define Help    0x5f
#define esc     0x45

#ifdef LUTMODE
#define TEXMAPNAME      (STRPTR)"tex128.lut8"
#define TEXMAPSIZE      128*128
#else
#define TEXMAPNAME      (STRPTR)"tex128.argb8888"
#define TEXMAPSIZE      128*128*4
#endif

void CloseAll(void);
void LocalWorld(Triangle3D *,int,float,float,float,int);


Triangle3D	polydata[] =
		{
#ifdef DEMO1
#include	"obj_ring.cdat"
#else
#include        "obj_cylinder.cdat"
#endif
		};

#ifdef LUTMODE

ULONG PaletteRGB32[770] =
{
	0x01000000,
	0x00000000,0x00000000,0x00000000,
	0x08888888,0x00000000,0x00000000,
	0x04444444,0x08888888,0x00000000,
	0x08888888,0x08888888,0x08888888,
	0x10000000,0x08888888,0x00000000,
	0x10000000,0x0CCCCCCC,0x08888888,
	0x18888888,0x08888888,0x04444444,
	0x08888888,0x18888888,0x0CCCCCCC,
	0x18888888,0x10000000,0x08888888,
	0x14444444,0x18888888,0x08888888,
	0x20000000,0x14444444,0x08888888,
	0x10000000,0x20000000,0x0CCCCCCC,
	0x1CCCCCCC,0x18888888,0x10000000,
	0x28888888,0x10000000,0x08888888,
	0x1CCCCCCC,0x20000000,0x10000000,
	0x1CCCCCCC,0x20000000,0x14444444,
	0x2DDDDDDD,0x18888888,0x08888888,
	0x31111111,0x10000000,0x08888888,
	0x2DDDDDDD,0x18888888,0x10000000,
	0x18888888,0x28888888,0x1CCCCCCC,
	0x28888888,0x20000000,0x10000000,
	0x2DDDDDDD,0x24444444,0x10000000,
	0x24444444,0x28888888,0x18888888,
	0x20000000,0x31111111,0x18888888,
	0x39999999,0x18888888,0x08888888,
	0x24444444,0x28888888,0x20000000,
	0x35555555,0x20000000,0x0CCCCCCC,
	0x31111111,0x28888888,0x14444444,
	0x28888888,0x31111111,0x18888888,
	0x39999999,0x20000000,0x10000000,
	0x41111111,0x18888888,0x0CCCCCCC,
	0x39999999,0x28888888,0x10000000,
	0x31111111,0x31111111,0x18888888,
	0x39999999,0x2DDDDDDD,0x18888888,
	0x35555555,0x31111111,0x20000000,
	0x49999999,0x18888888,0x0CCCCCCC,
	0x45555555,0x20000000,0x10000000,
	0x41111111,0x28888888,0x10000000,
	0x31111111,0x31111111,0x28888888,
	0x35555555,0x39999999,0x1CCCCCCC,
	0x41111111,0x31111111,0x18888888,
	0x39999999,0x39999999,0x24444444,
	0x51111111,0x18888888,0x0CCCCCCC,
	0x51111111,0x20000000,0x10000000,
	0x4DDDDDDD,0x28888888,0x10000000,
	0x4DDDDDDD,0x2DDDDDDD,0x18888888,
	0x45555555,0x35555555,0x1CCCCCCC,
	0x41111111,0x39999999,0x24444444,
	0x59999999,0x18888888,0x0CCCCCCC,
	0x41111111,0x39999999,0x28888888,
	0x49999999,0x39999999,0x18888888,
	0x39999999,0x41111111,0x28888888,
	0x59999999,0x20000000,0x10000000,
	0x51111111,0x31111111,0x14444444,
	0x49999999,0x39999999,0x20000000,
	0x59999999,0x28888888,0x14444444,
	0x51111111,0x39999999,0x18888888,
	0x41111111,0x41111111,0x2DDDDDDD,
	0x51111111,0x3DDDDDDD,0x20000000,
	0x59999999,0x31111111,0x14444444,
	0x51111111,0x39999999,0x2DDDDDDD,
	0x61111111,0x28888888,0x10000000,
	0x65555555,0x20000000,0x10000000,
	0x51111111,0x41111111,0x24444444,
	0x41111111,0x45555555,0x39999999,
	0x4DDDDDDD,0x45555555,0x31111111,
	0x59999999,0x39999999,0x20000000,
	0x61111111,0x31111111,0x18888888,
	0x5DDDDDDD,0x39999999,0x18888888,
	0x51111111,0x41111111,0x31111111,
	0x5DDDDDDD,0x3DDDDDDD,0x20000000,
	0x6DDDDDDD,0x28888888,0x14444444,
	0x4DDDDDDD,0x49999999,0x31111111,
	0x59999999,0x41111111,0x28888888,
	0x71111111,0x20000000,0x14444444,
	0x69999999,0x31111111,0x14444444,
	0x59999999,0x41111111,0x31111111,
	0x59999999,0x49999999,0x28888888,
	0x71111111,0x28888888,0x18888888,
	0x61111111,0x41111111,0x24444444,
	0x51111111,0x4DDDDDDD,0x39999999,
	0x71111111,0x31111111,0x18888888,
	0x6DDDDDDD,0x39999999,0x18888888,
	0x59999999,0x49999999,0x35555555,
	0x79999999,0x20000000,0x14444444,
	0x65555555,0x49999999,0x24444444,
	0x6DDDDDDD,0x39999999,0x20000000,
	0x79999999,0x28888888,0x14444444,
	0x61111111,0x49999999,0x31111111,
	0x71111111,0x41111111,0x18888888,
	0x51111111,0x51111111,0x45555555,
	0x79999999,0x31111111,0x10000000,
	0x79999999,0x31111111,0x18888888,
	0x59999999,0x51111111,0x3DDDDDDD,
	0x71111111,0x41111111,0x24444444,
	0x69999999,0x49999999,0x28888888,
	0x51111111,0x59999999,0x3DDDDDDD,
	0x79999999,0x39999999,0x1CCCCCCC,
	0x61111111,0x4DDDDDDD,0x39999999,
	0x69999999,0x4DDDDDDD,0x31111111,
	0x86666666,0x28888888,0x18888888,
	0x79999999,0x41111111,0x20000000,
	0x75555555,0x49999999,0x28888888,
	0x86666666,0x31111111,0x18888888,
	0x86666666,0x2DDDDDDD,0x20000000,
	0x65555555,0x51111111,0x3DDDDDDD,
	0x5DDDDDDD,0x59999999,0x45555555,
	0x82222222,0x39999999,0x18888888,
	0x82222222,0x39999999,0x28888888,
	0x79999999,0x4DDDDDDD,0x28888888,
	0x71111111,0x51111111,0x31111111,
	0x65555555,0x59999999,0x3DDDDDDD,
	0x69999999,0x51111111,0x45555555,
	0x82222222,0x41111111,0x20000000,
	0x8EEEEEEE,0x31111111,0x1CCCCCCC,
	0x7DDDDDDD,0x51111111,0x28888888,
	0x69999999,0x59999999,0x45555555,
	0x5DDDDDDD,0x59999999,0x51111111,
	0x8EEEEEEE,0x39999999,0x1CCCCCCC,
	0x75555555,0x51111111,0x35555555,
	0x82222222,0x49999999,0x24444444,
	0x75555555,0x59999999,0x31111111,
	0x8AAAAAAA,0x41111111,0x20000000,
	0x8EEEEEEE,0x39999999,0x28888888,
	0x75555555,0x59999999,0x35555555,
	0x75555555,0x51111111,0x41111111,
	0x61111111,0x61111111,0x4DDDDDDD,
	0x6DDDDDDD,0x59999999,0x49999999,
	0x86666666,0x51111111,0x2DDDDDDD,
	0x75555555,0x59999999,0x3DDDDDDD,
	0x96666666,0x3DDDDDDD,0x1CCCCCCC,
	0x8EEEEEEE,0x49999999,0x20000000,
	0x92222222,0x3DDDDDDD,0x28888888,
	0x8EEEEEEE,0x49999999,0x28888888,
	0x8AAAAAAA,0x51111111,0x20000000,
	0x96666666,0x41111111,0x20000000,
	0x69999999,0x61111111,0x4DDDDDDD,
	0x86666666,0x59999999,0x35555555,
	0x92222222,0x49999999,0x20000000,
	0x79999999,0x61111111,0x41111111,
	0x92222222,0x51111111,0x24444444,
	0x79999999,0x61111111,0x49999999,
	0x8EEEEEEE,0x59999999,0x28888888,
	0x71111111,0x61111111,0x51111111,
	0x92222222,0x51111111,0x28888888,
	0x9AAAAAAA,0x49999999,0x24444444,
	0x86666666,0x61111111,0x35555555,
	0x92222222,0x59999999,0x2DDDDDDD,
	0x75555555,0x69999999,0x51111111,
	0x86666666,0x61111111,0x45555555,
	0x92222222,0x59999999,0x35555555,
	0x79999999,0x61111111,0x55555555,
	0x8AAAAAAA,0x61111111,0x39999999,
	0x9EEEEEEE,0x51111111,0x20000000,
	0x71111111,0x69999999,0x59999999,
	0x9EEEEEEE,0x49999999,0x2DDDDDDD,
	0x9EEEEEEE,0x51111111,0x28888888,
	0x8AAAAAAA,0x65555555,0x41111111,
	0x7DDDDDDD,0x65555555,0x51111111,
	0x96666666,0x59999999,0x39999999,
	0x96666666,0x61111111,0x2DDDDDDD,
	0x9EEEEEEE,0x59999999,0x28888888,
	0x79999999,0x69999999,0x59999999,
	0x8AAAAAAA,0x69999999,0x45555555,
	0x82222222,0x69999999,0x51111111,
	0x79999999,0x69999999,0x61111111,
	0x9EEEEEEE,0x61111111,0x2DDDDDDD,
	0x9AAAAAAA,0x69999999,0x2DDDDDDD,
	0x8AAAAAAA,0x69999999,0x4DDDDDDD,
	0x82222222,0x69999999,0x59999999,
	0x9AAAAAAA,0x69999999,0x35555555,
	0x9EEEEEEE,0x69999999,0x31111111,
	0x9AAAAAAA,0x69999999,0x3DDDDDDD,
	0x75555555,0x71111111,0x69999999,
	0x8AAAAAAA,0x71111111,0x51111111,
	0x8EEEEEEE,0x69999999,0x59999999,
	0x9AAAAAAA,0x71111111,0x31111111,
	0x86666666,0x71111111,0x61111111,
	0x9AAAAAAA,0x69999999,0x45555555,
	0xA6666666,0x6DDDDDDD,0x28888888,
	0x9EEEEEEE,0x71111111,0x39999999,
	0x8EEEEEEE,0x71111111,0x59999999,
	0x9AAAAAAA,0x71111111,0x45555555,
	0x82222222,0x79999999,0x65555555,
	0xA2222222,0x75555555,0x31111111,
	0x8EEEEEEE,0x71111111,0x5DDDDDDD,
	0x9AAAAAAA,0x71111111,0x4DDDDDDD,
	0xA2222222,0x75555555,0x39999999,
	0x9EEEEEEE,0x79999999,0x3DDDDDDD,
	0x82222222,0x79999999,0x6DDDDDDD,
	0x8AAAAAAA,0x79999999,0x65555555,
	0x9AAAAAAA,0x79999999,0x49999999,
	0x9AAAAAAA,0x79999999,0x51111111,
	0x96666666,0x79999999,0x59999999,
	0xA6666666,0x79999999,0x3DDDDDDD,
	0x8EEEEEEE,0x79999999,0x6DDDDDDD,
	0x96666666,0x79999999,0x61111111,
	0x92222222,0x86666666,0x5DDDDDDD,
	0xA2222222,0x82222222,0x49999999,
	0xA6666666,0x79999999,0x4DDDDDDD,
	0x96666666,0x79999999,0x6DDDDDDD,
	0xA6666666,0x86666666,0x41111111,
	0x92222222,0x82222222,0x69999999,
	0x9EEEEEEE,0x82222222,0x59999999,
	0xA6666666,0x86666666,0x49999999,
	0xA2222222,0x86666666,0x51111111,
	0x92222222,0x82222222,0x6DDDDDDD,
	0xAAAAAAAA,0x8AAAAAAA,0x41111111,
	0x9EEEEEEE,0x86666666,0x5DDDDDDD,
	0x92222222,0x7DDDDDDD,0x79999999,
	0x96666666,0x86666666,0x71111111,
	0xAAAAAAAA,0x8AAAAAAA,0x45555555,
	0x9EEEEEEE,0x86666666,0x69999999,
	0x92222222,0x86666666,0x79999999,
	0xAAAAAAAA,0x8AAAAAAA,0x4DDDDDDD,
	0xA2222222,0x8EEEEEEE,0x59999999,
	0x9EEEEEEE,0x86666666,0x6DDDDDDD,
	0x92222222,0x8EEEEEEE,0x7DDDDDDD,
	0xAAAAAAAA,0x96666666,0x4DDDDDDD,
	0xA2222222,0x8EEEEEEE,0x65555555,
	0x9EEEEEEE,0x8AAAAAAA,0x75555555,
	0xAAAAAAAA,0x92222222,0x59999999,
	0xAAAAAAAA,0x9AAAAAAA,0x51111111,
	0x9EEEEEEE,0x8EEEEEEE,0x79999999,
	0xA6666666,0x92222222,0x69999999,
	0x92222222,0x8EEEEEEE,0x86666666,
	0xA6666666,0x9AAAAAAA,0x61111111,
	0x9EEEEEEE,0x8EEEEEEE,0x7DDDDDDD,
	0xA2222222,0x96666666,0x71111111,
	0xAAAAAAAA,0x9AAAAAAA,0x69999999,
	0x9EEEEEEE,0x92222222,0x86666666,
	0xA6666666,0x96666666,0x7DDDDDDD,
	0xA6666666,0x9EEEEEEE,0x75555555,
	0xAEEEEEEE,0x9EEEEEEE,0x69999999,
	0xAAAAAAAA,0x9EEEEEEE,0x75555555,
	0xA2222222,0x9AAAAAAA,0x8AAAAAAA,
	0xAAAAAAAA,0xA6666666,0x75555555,
	0xB2222222,0xA6666666,0x69999999,
	0xAAAAAAAA,0x9AAAAAAA,0x8AAAAAAA,
	0xB2222222,0xA6666666,0x75555555,
	0xAAAAAAAA,0xA6666666,0x82222222,
	0xA2222222,0x9EEEEEEE,0x96666666,
	0xAEEEEEEE,0x9EEEEEEE,0x8EEEEEEE,
	0xAAAAAAAA,0xA6666666,0x8AAAAAAA,
	0xAAAAAAAA,0xA6666666,0x96666666,
	0xA2222222,0xAEEEEEEE,0xA6666666,
	0xAEEEEEEE,0xAEEEEEEE,0x9AAAAAAA,
	0xB6666666,0xAAAAAAAA,0x96666666,
	0xAEEEEEEE,0xAEEEEEEE,0xA6666666,
	0xB6666666,0xB2222222,0x9EEEEEEE,
	0xB2222222,0xB2222222,0xA6666666,
	0xAEEEEEEE,0xB6666666,0xAEEEEEEE,
	0xB2222222,0xBEEEEEEE,0xAEEEEEEE,
	0xB2222222,0xBEEEEEEE,0xB2222222,
	0xB6666666,0xC6666666,0xB6666666,
	0xBAAAAAAA,0xC6666666,0xBEEEEEEE,
	0x00000000
};
#endif

#define NPOLY   ((sizeof(polydata)/sizeof(Triangle3D)))


struct  IntuitionBase   *IntuitionBase = NULL;
struct  GfxBase         *GfxBase = NULL;
struct  Library         *CyberGfxBase = NULL;
struct  Library         *CGX3DVirginBase=0;
struct  Library         *LowLevelBase=0;
View3D          v3d=0;
TexHandle       th=0;
UBYTE           BufNum=0;
APTR            TexelMap=0;



void	main(int argc,char *argv[])
{
        float wz=0.0,wx=0.0,wy=0.0;
        int	gz = 2000;
        struct  ExecBase *ExecBase=(struct ExecBase *)*((ULONG *)4L);
        struct MsgPort *eventmp;
        BOOL Update=FALSE;
        struct IntuiMessage *msg = NULL;

#ifdef _M68881
        if(!(ExecBase->AttnFlags & AFF_68881))
        {
         printf("You need at least a 68881 floating point unit !\n");
         return;
        }
#endif

	if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L)))
		{ printf ("ERROR: Couldn't open intuition.library\n"); CloseAll(); }

  	if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L)))
		{ printf ("ERROR: Couldn't open graphics.library\n"); CloseAll(); }


  	if (!(CyberGfxBase=(struct Library *)OpenLibrary("cybergraphics.library",41L)))
		{ printf ("ERROR: Couldn't open cybergraphics.library\n"); CloseAll(); }


	if (!(CGX3DVirginBase=(struct Library *)OpenLibrary("cgx3dvirgin.library",2L)))
		{ printf ("ERROR: Couldn't open cgx3dvirgin.library v2\n"); CloseAll(); }

        if(LowLevelBase = OpenLibrary("lowlevel.library",40L))
        {
         SetJoyPortAttrs(1L,
                          SJA_Type, SJA_TYPE_GAMECTLR,
                          TAG_DONE);
        }

#ifndef DEMO4
        if(TexelMap = AllocVec(TEXMAPSIZE,MEMF_CLEAR))
        {
         BPTR fh;
         ULONG i;

	 if(fh=Open(TEXMAPNAME,MODE_OLDFILE))
 	 {
	  Read(fh,TexelMap,TEXMAPSIZE);
	  Close(fh);
	 }
         else
         {
          printf("Unable to load texture datafile !\n");
          CloseAll();
         }

	for (i=0;i<NPOLY;i++)
	{
         polydata[i].p1.u *= 2;
         polydata[i].p2.u *= 2;
         polydata[i].p3.u *= 2;
#ifdef DEMO1
         polydata[i].p1.v *= 2;
         polydata[i].p2.v *= 2;
         polydata[i].p3.v *= 2;
#else
         polydata[i].p1.v *= 4;
         polydata[i].p2.v *= 4;
         polydata[i].p3.v *= 4;
#endif
        }

        }
#endif


        if(!(v3d=V3D_OpenViewTags(DISPLAYWIDTH,
                                  DISPLAYHEIGHT,
#ifdef LUTMODE
                                  8,
                                  V3DVA_Colors32,     PaletteRGB32,
#else
                                  15,
#endif                               

#ifdef DEMO1
                                  V3DVA_UseZBuffer,   TRUE,          // Demo1 needs zbuffering
#else
                                  V3DVA_UseZBuffer,   FALSE,
#endif
                                  TAG_DONE)))
        {
         printf("Unable to open a 3D view !\n");
         CloseAll();
        }

 
        if(!(eventmp=V3D_CreateEventPort(v3d,IDCMP_RAWKEY|IDCMP_INTUITICKS)))
        {
         printf("Unable to create event port for idcmp messages !\n");
         CloseAll();
        }

#ifndef DEMO4
        if(!(th=V3D_CreateTexHandleTags(v3d,
                                        V3DTHA_TexelMap,     TexelMap,
                                        V3DTHA_MapSize,      128,
#ifdef LUTMODE
                                        V3DTHA_TexClrFmt,    TEXFMT_LUT8,
                                        V3DTHA_FilterMode,   FLTRMD_1TPP,
#else
                                        V3DTHA_TexClrFmt,    TEXFMT_ARGB8888,
                                        V3DTHA_FilterMode,   FLTRMD_1TPP,
#endif
                                        V3DTHA_TexWrap,      TRUE,
#ifdef DEMO3
                                        V3DTHA_LitTexture,   TRUE,
#else
                                        V3DTHA_LitTexture,   FALSE,
#endif
                                        TAG_DONE)))
        {
         printf("Unable to create texture handle !\n");
         CloseAll();
        }
#endif
                         
	LocalWorld(polydata,NPOLY,wx,wy,wz,gz);

	while(1)
	{
//         Wait(1L<<eventmp->mp_SigBit);

                     if(LowLevelBase)
                      {
                       ULONG state;

                       state=ReadJoyPort(1L);

                       if(state & JP_TYPE_GAMECTLR)
                        {
                         if(state & (JP_BUTTON_MASK|JP_DIRECTION_MASK))
                         {

                         if(state & JPF_JOY_UP)
                         {
                          wx+= ADDING;
                          Update = TRUE;
                         }

                         if(state & JPF_JOY_DOWN)
                         {
                          wx-= ADDING;
                          Update = TRUE;
                         }

                         if(state & JPF_JOY_LEFT)
                         {
                          wy-= ADDING;
                          Update = TRUE;
                         }

                         if(state & JPF_JOY_RIGHT)
                         {
                          wy+= ADDING;
                          Update = TRUE;
                         }

                         if(state & JPF_BUTTON_FORWARD)
                         {
                          if( gz > 600)
                          { gz-= 50;
                            Update = TRUE;
                          }
                         }

                         if(state & JPF_BUTTON_REVERSE)
                         {
                          gz+= 50;
                          Update = TRUE;
                         }


                         if(state & JPF_BUTTON_GREEN)
                         {
                          wz+= ADDING;
                          Update = TRUE;
                         }

                         if(state & JPF_BUTTON_YELLOW)
                         {
                          wz-= ADDING;
                          Update = TRUE;
                         }
                         }
                        }
                        
                      }

            while(msg=(struct IntuiMessage *)GetMsg(eventmp))
            {
             switch(msg->Class)
             {
                case IDCMP_INTUITICKS:
                     {
                     }
                     break;
                case IDCMP_RAWKEY:
                     {
                        int Code=msg->Code;

                        if(!(Code & 0x80))
                        {
                         Code&=0x7f;
                       switch(Code)
                       {
                         case Up   : wx+= ADDING; Update=TRUE; break;
                         case Down : wx-= ADDING; Update=TRUE; break;
                         case Right: wy+= ADDING; Update=TRUE; break;
                         case Left : wy-= ADDING; Update=TRUE; break;
                         case AUp   : wx+= ADDING; Update=TRUE; break;
                         case ADown : wx-= ADDING; Update=TRUE; break;
                         case ARight: wy+= ADDING; Update=TRUE; break;
                         case ALeft : wy-= ADDING; Update=TRUE; break;
                         case AAxUp   : wz+= ADDING; Update=TRUE; break;
                         case AAxDown : wz-= ADDING; Update=TRUE; break;
                         case Plus   : if( gz > 200)
                                        { gz-= 50; Update=TRUE; }
                                       break;
                         case Minus  : gz+= 50; Update=TRUE; break;
        
                         case esc:   CloseAll();
                       }
                     }
                     break;
             };

             }
               ReplyMsg((struct Message *)msg);

	}
         if(Update==TRUE) LocalWorld(polydata,NPOLY,wx,wy,wz,gz);
         Update=FALSE;
        }

	CloseAll();
}


/***********************************************************************************\
*																												*
*		CloseAll																								*
*																												*
\***********************************************************************************/

void CloseAll()
{
        if(th)  V3D_DeleteTexHandle(th);
        if(TexelMap) FreeVec(TexelMap);
        if(v3d) V3D_CloseView(v3d);
	if (IntuitionBase) CloseLibrary ((struct Library *)IntuitionBase);
	if (GfxBase) CloseLibrary ((struct Library *)GfxBase);
	if (CGX3DVirginBase) CloseLibrary ((struct Library *)CGX3DVirginBase);
	if (CyberGfxBase) CloseLibrary ((struct Library *)CyberGfxBase);
        if (LowLevelBase) CloseLibrary ((struct Library *)LowLevelBase);
	exit(0);
}


/* Most important function AT ALL ;) */

/* Returns TRUE if line was clipped, elsewhere returns false */

BOOL LeftClipping(long *xs, long *ys, long *xe, long *ye, long *us, long *vs, long *ue, long *ve)
{
	LONG 	adding;
	if(*xs<0) {
		if(*xe>0) {
			if(*xe-*xs) {
				adding = ((*ue-*us)<<20) / (*xe-*xs);
				*us += (-*xs * adding)>>20;

				adding = ((*ve-*vs)<<20) / (*xe-*xs);
				*vs += (-*xs * adding)>>20;


				adding = ((*ye-*ys)<<20) / (*xe-*xs);
				*ys += (-*xs * adding)>>20;

				*xs = 0;
			}

			return(TRUE);
		} else {
			return(FALSE);
		}
	}
}


/* Whole wizardry ;) */

long V3D_DrawClippedTriangle3D(View3D v3d,
                         Triangle3D *t3d,
                         ULONG blendmd)
{
	long hx,hy,hu,hv;
	if((t3d->p1.x<0) && (t3d->p2.x<0) && (t3d->p3.x>=0)) {
		LeftClipping(&t3d->p1.x, &t3d->p1.y, &t3d->p3.x, &t3d->p3.y, &t3d->p1.u, &t3d->p1.v, &t3d->p3.u, &t3d->p3.v);
		LeftClipping(&t3d->p2.x, &t3d->p2.y, &t3d->p3.x, &t3d->p3.y, &t3d->p2.u, &t3d->p2.v, &t3d->p3.u, &t3d->p3.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);
		return(0);
	}

	if((t3d->p2.x<0) && (t3d->p3.x<0) && (t3d->p1.x>=0)) {
		LeftClipping(&t3d->p2.x, &t3d->p2.y, &t3d->p1.x, &t3d->p1.y, &t3d->p2.u, &t3d->p2.v, &t3d->p1.u, &t3d->p1.v);
		LeftClipping(&t3d->p3.x, &t3d->p3.y, &t3d->p1.x, &t3d->p1.y, &t3d->p3.u, &t3d->p3.v, &t3d->p1.u, &t3d->p1.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);
		return(0);
	}

	if((t3d->p1.x<0) && (t3d->p3.x<0) && (t3d->p2.x>=0)) {
		LeftClipping(&t3d->p1.x, &t3d->p1.y, &t3d->p2.x, &t3d->p2.y, &t3d->p1.u, &t3d->p1.v, &t3d->p2.u, &t3d->p2.v);
		LeftClipping(&t3d->p3.x, &t3d->p3.y, &t3d->p2.x, &t3d->p2.y, &t3d->p3.u, &t3d->p3.v, &t3d->p2.u, &t3d->p2.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);
		return(0);
	}

	if((t3d->p1.x>=0) && (t3d->p3.x>=0) && (t3d->p2.x>=0)) {
		V3D_DrawTriangle3D(v3d, t3d, blendmd);
		return(0);
	}


	if((t3d->p1.x<0) && (t3d->p2.x>=0) && (t3d->p3.x>=0)) {
		hx = t3d->p1.x;
		hy = t3d->p1.y;
		hu = t3d->p1.u;
		hv = t3d->p1.v;

		LeftClipping(&t3d->p1.x, &t3d->p1.y, &t3d->p2.x, &t3d->p2.y, &t3d->p1.u, &t3d->p1.v, &t3d->p2.u, &t3d->p2.v);		
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		t3d->p2.x = hx;
		t3d->p2.y = hy;
		t3d->p2.u = hu;
		t3d->p2.v = hv;
		LeftClipping(&t3d->p2.x, &t3d->p2.y, &t3d->p3.x, &t3d->p3.y, &t3d->p2.u, &t3d->p2.v, &t3d->p3.u, &t3d->p3.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		return(0);
	}

	if((t3d->p1.x>=0) && (t3d->p2.x<0) && (t3d->p3.x>=0)) {
		hx = t3d->p2.x;
		hy = t3d->p2.y;
		hu = t3d->p2.u;
		hv = t3d->p2.v;

		LeftClipping(&t3d->p2.x, &t3d->p2.y, &t3d->p1.x, &t3d->p1.y, &t3d->p2.u, &t3d->p2.v, &t3d->p1.u, &t3d->p1.v);		
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		t3d->p1.x = hx;
		t3d->p1.y = hy;
		t3d->p1.u = hu;
		t3d->p1.v = hv;
		LeftClipping(&t3d->p1.x, &t3d->p1.y, &t3d->p3.x, &t3d->p3.y, &t3d->p1.u, &t3d->p1.v, &t3d->p3.u, &t3d->p3.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		return(0);
	}

	if((t3d->p1.x>=0) && (t3d->p2.x>=0) && (t3d->p3.x<0)) {
		hx = t3d->p3.x;
		hy = t3d->p3.y;
		hu = t3d->p3.u;
		hv = t3d->p3.v;

		LeftClipping(&t3d->p3.x, &t3d->p3.y, &t3d->p1.x, &t3d->p1.y, &t3d->p3.u, &t3d->p3.v, &t3d->p1.u, &t3d->p1.v);		
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		t3d->p1.x = hx;
		t3d->p1.y = hy;
		t3d->p1.u = hu;
		t3d->p1.v = hv;
		LeftClipping(&t3d->p1.x, &t3d->p1.y, &t3d->p2.x, &t3d->p2.y, &t3d->p1.u, &t3d->p1.v, &t3d->p2.u, &t3d->p2.v);
		V3D_DrawTriangle3D(v3d, t3d, blendmd);

		return(0);
	}
}


void LocalWorld(Triangle3D in[],int cnt,float wx,float wy,float wz,int z)
{
        int		i;
        float		cosx,sinx,cosy,siny,cosz,sinz;
        Triangle3D	zws1,zws2,zws3;

	cosx = cos(wx);
	sinx = sin(wx);

	cosy = cos(wy);
	siny = sin(wy);

	cosz = cos(wz);
	sinz = sin(wz);

        if(V3D_LockView(v3d))
        {

         V3D_ClearBuffer(v3d,BufNum);

#ifdef DEMO1
         V3D_ClearZBuffer(v3d);
#endif

	 for (i=0;i<cnt;i++)                /* Index of In  Poligons */
	 {
		/* rotate in Y  */

		zws1.p1.x	=	cosy*in[i].p1.x-siny*in[i].p1.z;
		zws1.p2.x	=	cosy*in[i].p2.x-siny*in[i].p2.z;
		zws1.p3.x	=	cosy*in[i].p3.x-siny*in[i].p3.z;

		zws1.p1.y	=	in[i].p1.y;
		zws1.p2.y	=	in[i].p2.y;
		zws1.p3.y	=	in[i].p3.y;

		zws1.p1.z	=	siny*in[i].p1.x+cosy*in[i].p1.z;
		zws1.p2.z	=	siny*in[i].p2.x+cosy*in[i].p2.z;
		zws1.p3.z	=	siny*in[i].p3.x+cosy*in[i].p3.z;


		/* rotate in X  */

		zws2.p1.x	=	zws1.p1.x;
		zws2.p2.x	=	zws1.p2.x;
		zws2.p3.x	=	zws1.p3.x;

		zws2.p1.y	=	cosx*zws1.p1.y+sinx*zws1.p1.z;
		zws2.p2.y	=	cosx*zws1.p2.y+sinx*zws1.p2.z;
		zws2.p3.y	=	cosx*zws1.p3.y+sinx*zws1.p3.z;

		zws2.p1.z	=	-sinx*zws1.p1.y+cosx*zws1.p1.z;
		zws2.p2.z	=	-sinx*zws1.p2.y+cosx*zws1.p2.z;
		zws2.p3.z	=	-sinx*zws1.p3.y+cosx*zws1.p3.z;


		/* rotate in Z  */

		zws1.p1.x	=	cosz*zws2.p1.x+sinz*zws2.p1.y;
		zws1.p2.x	=	cosz*zws2.p2.x+sinz*zws2.p2.y;
		zws1.p3.x	=	cosz*zws2.p3.x+sinz*zws2.p3.y;

		zws1.p1.y	=	-sinz*zws2.p1.x+cosz*zws2.p1.y;
		zws1.p2.y	=	-sinz*zws2.p2.x+cosz*zws2.p2.y;
		zws1.p3.y	=	-sinz*zws2.p3.x+cosz*zws2.p3.y;

		zws1.p1.z	=	zws2.p1.z;
		zws1.p2.z	=	zws2.p2.z;
		zws1.p3.z	=	zws2.p3.z;


		/* move */

		zws3.p1.z	=	zws1.p1.z + z ;
		zws3.p2.z	=	zws1.p2.z + z ;
		zws3.p3.z	=	zws1.p3.z + z ;

		zws3.p1.x	=	((zws1.p1.x*FOCUS)/(zws3.p1.z*1.0)+.5) + WINX/2;
		zws3.p2.x	=	((zws1.p2.x*FOCUS)/(zws3.p2.z*1.0)+.5) + WINX/2;
		zws3.p3.x	=	((zws1.p3.x*FOCUS)/(zws3.p3.z*1.0)+.5) + WINX/2;

		zws3.p1.y	=	((zws1.p1.y*FOCUS)/(zws3.p1.z*1.0)+.5) + WINY/2;
		zws3.p2.y	=	((zws1.p2.y*FOCUS)/(zws3.p2.z*1.0)+.5) + WINY/2;
		zws3.p3.y	=	((zws1.p3.y*FOCUS)/(zws3.p3.z*1.0)+.5) + WINY/2;


		zws3.p1.u	=	((in[i].p1.u*1.0)+.5);
		zws3.p2.u	=	((in[i].p2.u*1.0)+.5);
		zws3.p3.u	=	((in[i].p3.u*1.0)+.5);

		zws3.p1.v	=	((in[i].p1.v*1.0)+.5);
		zws3.p2.v	=	((in[i].p2.v*1.0)+.5);
		zws3.p3.v	=	((in[i].p3.v*1.0)+.5);

                zws3.p1.color = in[i].p1.color;
                zws3.p2.color = in[i].p2.color;
                zws3.p3.color = in[i].p3.color;

/* #ifndef DEMO1 */
        //       only draw visible triangle (area normal to viewer)
/* This is needed always ;) */
		if (  ( (zws3.p2.x-zws3.p1.x) * (zws3.p3.y-zws3.p2.y) -
			(zws3.p3.x-zws3.p2.x) * (zws3.p2.y-zws3.p1.y)
                      ) <0)
/* #endif */
		{
                 zws3.th = th;

                 V3D_DrawClippedTriangle3D(v3d,
                                    &zws3,
#ifndef DEMO3
                                    BLENDMD_DECAL
#else
                                    BLENDMD_MODULATE
#endif
                                   );

		 }
	 }

         V3D_UnLockView(v3d);
        }
        BufNum++;
        BufNum&=1;

        V3D_FlipBuffer(v3d,BufNum);
}

