
// 3ddos.cpp

#include "stdgfx.h"
#include "mpgui.h"
#include "mpg3d.h"

BOOLEAN ReadConfigFile ( STRING FileName );
VOID HandleInput ( G3DSYSTEM* G3D, G3DCAMERA *Camera );
BOOLEAN Create3DDatabase ( G3DSYSTEM *G3D );
VOID DoBenchMark ( G3DSYSTEM *G3D );

IMAGE *VScreen;
INT VideoMode;
BOOLEAN Debug;
float ViewDistance;
float NearClipZ;
BOOLEAN DepthCueing = FALSE;
float DepthScale = 1;
BOOLEAN DoHaze = FALSE;
COLORTABLE *HazeTable;
CHAR HazeTableName[128];
float HazeScale = 1;

CHAR ObjectFileName[128];
float ScaleFactor = 1.0;
BOOLEAN ClockWise = FALSE;
float ObjPosX,ObjPosY,ObjPosZ;
float ObjRotX,ObjRotY,ObjRotZ;
float MaxVisibleDistance;
BOOLEAN LoadAll;

CHAR TextureFileName[128];
BOOLEAN MapTexture;
float U0,V0;
float U1,V1;
float U2,V2;
LONG TextureType;
ANIMIMAGE *Texture;
LONG TextureNumFrames=0;
LONG CurTextureFrame=0;

CHAR ShadeTableFileName[128];
COLORTABLE *ShadeTable;
float LightPosX,LightPosY,LightPosZ;
float LightMaxIntensity;
float LightMinIntensity;
INT AmbientRed,AmbientGreen,AmbientBlue;
BOOLEAN FollowCamera=TRUE;
G3DLIGHT *MyLight;

float CameraPosX,CameraPosY,CameraPosZ;
float CameraAngX,CameraAngY,CameraAngZ;
float AddX,AddY,AddZ;

BOOLEAN BGBitMap;
CHAR BGFileName[128];
IMAGE *BGImage;
INT BGRed,BGGreen,BGBlue;
BYTE BGColor;

BOOLEAN UseTransparent;
COLORTABLE *BlendTable;
CHAR BlendFileName[128];

BOOLEAN ReadConfigFile ( STRING FileName )
  {
    FILEHANDLE f;
    
    f = File.Open ( FileName, OPEN_READ );
    if (f==NULL)
      {
        printf ("Can not open this file!\n" );
        return FAILURE;
      } // End else

    CHAR Str[128];
    printf ( "Screen Section\n" );
    fscanf ( f, "SCREEN\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    MODE = %s\n", Str );    
    if (strcmp(Str,"320x200x256")==0)
      VideoMode = M320x200x256;
    else if (strcmp(Str,"640x400x256")==0)
      VideoMode = M640x400x256;
    else if (strcmp(Str,"640x480x256")==0)
      VideoMode = M640x480x256;
    else if (strcmp(Str,"800x600x256")==0)
      VideoMode = M800x600x256;
    else if (strcmp(Str,"1024x768x256")==0)
      VideoMode = M1024x768x256;
    else
      {
        printf ("Unknown Video Mode!\n" );
        return FAILURE;
      } // End else      
    printf ( "  Screen = %s\n", Str );

    fscanf ( f, "    DEBUG = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      Debug = TRUE;
    else
      Debug = FALSE;

    printf ( "  Debug = %s\n", Str );

    fscanf ( f, "    VIEW DISTANCE = %f\n", &ViewDistance );
    printf ( "  View Distance = %f\n", ViewDistance );

    fscanf ( f, "    NEAR CLIP Z = %f\n", &NearClipZ );
    printf ( "  Near Clip Z = %f\n", NearClipZ );
    
    fscanf ( f, "    DEPTH CUE = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      DepthCueing = TRUE;
    else
      DepthCueing = FALSE;
    printf ( "  Depth Cueing = %s\n", Str );

    fscanf ( f, "    DEPTH SCALE = %f\n", &DepthScale );
    printf ( "  Depth Scale = %f\n", DepthScale );
      
    fscanf ( f, "    HAZE = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      DoHaze = TRUE;
    else
      DoHaze = FALSE;
    printf ( "  Haze = %s\n", Str );

    fscanf ( f, "    HAZE FILE = %s\n", HazeTableName );
    printf ( "  HAZE FILE = %s\n", HazeTableName );

    fscanf ( f, "    HAZE SCALE = %f\n", &HazeScale );
    printf ( "  Haze File = %f\n", HazeScale );
      
    fscanf ( f, "  END\n" );      
    fscanf ( f, "\n" );
    printf ( "End of Screen Section\n\n" );
    
    printf ( "Object Section\n" );
    fscanf ( f, "OBJECT\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    FILE = %s\n", ObjectFileName );
    printf ( "  Object File = %s\n", ObjectFileName );

    fscanf ( f, "    POSITION = %f %f %f\n", &ObjPosX, &ObjPosY, &ObjPosZ );    
    printf ( "  Position = %f %f %f\n", ObjPosX, ObjPosY, ObjPosZ );

    fscanf ( f, "    SCALE = %f\n", &ScaleFactor );
    printf ( "  Scale = %f\n", ScaleFactor );

    fscanf ( f, "    MAX VISIBLE DISTANCE = %f\n", &MaxVisibleDistance );
    printf ( "  Max Visible Distance = %f\n", MaxVisibleDistance );

    fscanf ( f, "    ROTATE = %f %f %f\n", &ObjRotX, &ObjRotY, &ObjRotZ );
    printf ( "  Rotate = %f %f %f\n", ObjRotX, ObjRotY, ObjRotZ );

    fscanf ( f, "    LOAD ALL = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      LoadAll = TRUE;
    else
      LoadAll = FALSE;  
    printf ( "  Load All = %s\n", Str );

    fscanf ( f, "    CLOCKWISE = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      ClockWise = TRUE;
    else
      ClockWise = FALSE;  
    printf ( "  Clock Wise = %s\n", Str );

    fscanf ( f, "  END\n" );
    fscanf ( f, "\n" );
    printf ( "End of Object Section\n\n" );
    
    printf ( "Material Section\n" );
    fscanf ( f, "MATERIAL\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    FILE = %s\n", TextureFileName );
    printf ( "  Texture File %s\n", TextureFileName );

    fscanf ( f, "    TYPE = %s\n", Str );    
    if (strcmp(Str,"STATIC")==0)
      TextureType = TEXTURE_STATIC;
    else if (strcmp(Str,"FLIC")==0)
      TextureType = TEXTURE_FLIC;
    else if (strcmp(Str,"ANIM")==0)
      TextureType = TEXTURE_ANIM;
    else
      TextureType = 0;  
    printf ( "  Type %s\n", Str );

    fscanf ( f, "    AMBIENT = %d %d %d\n", &AmbientRed, &AmbientGreen, &AmbientBlue );
    printf ( "  Ambient = %d %d %d\n", AmbientRed, AmbientGreen, AmbientBlue );

    fscanf ( f, "    MAP TEXTURE = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      MapTexture = TRUE;
    else
      MapTexture = FALSE;  
    printf ( "  Map Texture = %s\n", Str );

    fscanf ( f, "    U0 V0 = %f %f\n", &U0, &V0 );
    printf ( "U0 = %f  V0 = %f\n", U0, V0 );
    fscanf ( f, "    U1 V1 = %f %f\n", &U1, &V1 );
    printf ( "U1 = %f  V1 = %f\n", U1, V1 );
    fscanf ( f, "    U2 V2 = %f %f\n", &U2, &V2 );
    printf ( "U2 = %f  V2 = %f\n", U2, V2 );
    
    fscanf ( f, "    TRANSPARENT = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      UseTransparent = TRUE;
    else
      UseTransparent = FALSE;  
    printf ( "  Transparent = %s\n", Str );

    fscanf ( f, "  END\n" );
    fscanf ( f, "\n" );
    printf ( "End of Material Section\n\n" );
        
    printf ( "Light Section\n" );
    fscanf ( f, "LIGHT\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    FILE = %s\n", ShadeTableFileName );
    printf ( "  Shade Table File = %s\n", ShadeTableFileName );

    fscanf ( f, "    POSITION = %f %f %f\n", &LightPosX, &LightPosY, &LightPosZ );
    printf ( "  Position = %f %f %f\n", LightPosX, LightPosY, LightPosZ );

    fscanf ( f, "    FOLLOW CAMERA = %s\n", Str );
    if (strcmp(Str,"YES")==0)
      FollowCamera = TRUE;
    else
      FollowCamera = FALSE;  
    printf ( "  FOLLOW CAMERA = %s\n", Str );
    
    fscanf ( f, "    MAX INTENSITY = %f\n", &LightMaxIntensity );
    printf ( "  Max Intensity = %f\n", LightMaxIntensity );

    fscanf ( f, "    MIN INTENSITY = %f\n", &LightMinIntensity );
    printf ( "  Min Intensity = %f\n", LightMinIntensity );

    fscanf ( f, "  END\n" );
    fscanf ( f, "\n" );
    printf ( "End of Light Section\n\n" );
        
    printf ( "Camera Section\n" );
    fscanf ( f, "CAMERA\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    POSITION = %f %f %f\n", &CameraPosX, &CameraPosY, &CameraPosZ );
    printf ( "  Position = %f %f %f\n", CameraPosX, CameraPosY, CameraPosZ );

    fscanf ( f, "    ANGLE = %f %f %f\n", &CameraAngX, &CameraAngY, &CameraAngZ );
    printf ( "  Angle = %f %f %f\n", CameraAngX, CameraAngY, CameraAngZ );

    fscanf ( f, "  END\n" );
    fscanf ( f, "\n" );
    printf ( "End of Camera Section\n\n" );

    printf ( "Background Section\n" );
    fscanf ( f, "BACKGROUND\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    FILE = %s\n", BGFileName );
    if (strcmp(BGFileName,"NULL")==0)
      BGBitMap = FALSE;
    else
      BGBitMap = TRUE;
    printf ( "  Background File Name = %s\n", BGFileName );

    fscanf ( f, "    COLOR = %d %d %d\n", &BGRed, &BGGreen, &BGBlue );
    printf ( "  Color = %d %d %d\n", BGRed, BGGreen, BGBlue );

    fscanf ( f, "  END\n" );
    fscanf ( f, "\n" );
    printf ( "End of Background Section\n\n" );

    printf ( "Color Blending Section\n" );
    fscanf ( f, "COLOR BLENDING\n" );
    fscanf ( f, "  BEGIN\n" );
    fscanf ( f, "    FILE = %s\n", BlendFileName );
    printf ( "  Blend File Name = %s\n", BlendFileName );

    fscanf ( f, "  END\n" );
    printf ( "End of Color Blending Section\n\n" );

    File.Close ( f );

    return SUCCESS;    
  } // End of ReadConfigFile

BOOLEAN BenchMark = FALSE;

MAINPROGRAM
  BEGIN
    printf ("\n3D Program Demo ver 2.0\n" );
    printf ("    By Toshiaki Tsuji\n\n" );

    U0 = V0 = (float)0;
    U1 = (float)0;
    V1 = (float)0.25;
    U2 = V2 = (float)0.25;
    
    VScreen = new IMAGE ( IMAGE_TOPDOWN );
    BGImage = new IMAGE ( IMAGE_TOPDOWN );
    ShadeTable = new COLORTABLE ();
    BlendTable = new COLORTABLE ();
    HazeTable = new COLORTABLE ();

    if (GetNumArgs()==0)
      {
        printf ("You must specify config file!\n" );
        exit (0);
      } // End if
    if (GetNumArgs()==2)
      {
        CHAR ExStr[128];
        GetArg ( 1, ExStr );
        
        if (strcmp( ExStr, "/b")==0)
          BenchMark = TRUE; 
      } // End if  

    CHAR ConfigFile[128];
    
    GetArg ( 0, ConfigFile );
    printf ( "Initializing please wait ...\n\n" );
    if (ReadConfigFile ( ConfigFile )==FAILURE)
      {
        printf ("Error reading config file!\n" );
        exit (0);
      } // End if
    else
      {
        printf ("Config File Loaded.\n\n" );
      } // End if      
    
    G3DSYSTEM G3D;
    G3DCAMERA Camera;
    
    Camera.Move ( CameraPosX, CameraPosY, CameraPosZ );
    Camera.SetAngle ( CameraAngX, CameraAngY, CameraAngZ );

    G3D.SetDestination ( VScreen );
    G3D.SetViewDistance ( ViewDistance );
    G3D.SetNearClipZ ( NearClipZ );
    G3D.SetDepthCueing ( DepthCueing, DepthScale );
    
    if (Create3DDatabase(&G3D)==FAILURE)
      {
        printf ("Error creating 3D environment!\n" );
        exit (0);
      } // End if          
    
    G3D.Init ();

    DISPLAYDATA DisplayData;
    DisplayData.Mode = VideoMode;
    
    Grafix.SetDisplay ( &DisplayData );
    Grafix.SetPalette ( HVGA, ShadeTable->GetPalette () );
    
    if (Debug)
      VScreen->SetDebugFlag ( TRUE );
    
    VScreen->Create ( IMAGE_8BIT, Grafix.GetWidth ( HVGA ), Grafix.GetHeight ( HVGA ) );

    G3D.SetScreenCenter ( VScreen->GetWidth()/2, VScreen->GetHeight()/2 );

    Input.Init ();

    LONG Count;
    Count = 0;    

    MYTIMER MyTimer;
    MyTimer.StartTimer ();

    G3DOBJECT *Object;
    Object = G3D.FindObjectByID ( 1 );

    IMAGE *DisplayBG = NULL;
    if (BGBitMap)
      {
        DisplayBG = new IMAGE ( IMAGE_TOPDOWN );
        DisplayBG->Create ( IMAGE_8BIT, VScreen->GetWidth(), VScreen->GetHeight() );
        Grafix.SetScaleFactor ( DisplayBG->GetWidth(), BGImage->GetWidth(),
                                DisplayBG->GetHeight(), BGImage->GetHeight() );
        Grafix.ScaleImage ( BGImage, 0, 0, BGImage->GetWidth(), BGImage->GetHeight(),
                            DisplayBG, 0, 0 );
        Grafix.SetScaleFactor ( 1, 1, 1, 1 );
      } // End if

    if (BenchMark)
      {
        DoBenchMark ( &G3D );
        exit(0);
      } // End if
      
    while (Input.IsKeyDown( SC_ESC )==FALSE)
      {
        AddX = AddY = AddZ = 0;
        Count++;
        if (BGBitMap!=TRUE)
          VScreen->Clear ( BGColor );
        else
          {
            Grafix.CopyImage ( DisplayBG, 0, 0, DisplayBG->GetWidth(),
                               DisplayBG->GetHeight(),
                               VScreen, 0, 0 );
          } // End if

        if (Object!=NULL)
          Object->Rotate ( ObjRotX, ObjRotY, ObjRotZ );
        if (TextureNumFrames)
          {
            Texture->SetFrame ( CurTextureFrame++ );
            if (CurTextureFrame>=TextureNumFrames)
              CurTextureFrame = 0;
          } // End if

        HandleInput ( &G3D, &Camera );
        G3D.ShowView ( &Camera );
        Grafix.DisplayImage ( HVGA, VScreen, 0, 0, VScreen->GetWidth(),
                              VScreen->GetHeight(), 0, 0 );
      } // End while
    MyTimer.EndTimer ();

    Input.DeInit ();
    
    Grafix.ResetDisplay ();

    float FrameRate;
    FrameRate = MyTimer.GetFrameRate ( Count );

    printf ( "Frame rate was %4.2f fps.\n", FrameRate );

    delete VScreen;
    delete ShadeTable;
    if (DisplayBG!=NULL)
      delete DisplayBG;
    delete BGImage;  
    return 0;
  END // End of Main Program
  
VOID HandleInput ( G3DSYSTEM* G3D, G3DCAMERA *Camera )
  {
    if (Input.IsKeyDown(SC_F))
      {
        G3D->SetShadeFlags ( SHADE_FLAT );  
      } // End if
    else if (Input.IsKeyDown(SC_G))
      {
        G3D->SetShadeFlags ( SHADE_GOURAUD );  
      } // End else
    else if (Input.IsKeyDown(SC_N))
      {
        G3D->SetShadeFlags ( SHADE_NONE );  
      } // End else

    if (Input.IsKeyDown(SC_S))
      {
        G3D->SetFaceFlags ( FACE_SOLID );  
      } // End if
    else if (Input.IsKeyDown(SC_T))
      {
        G3D->SetFaceFlags ( FACE_TEXTURE );  
      } // End else
    else if (Input.IsKeyDown(SC_W))
      {
        G3D->SetFaceFlags ( FACE_WIREFRAME );  
      } // End else

    G3DMATERIALLIB *MaterialLib;
    G3DMATERIAL *Material;

    MaterialLib = G3D->GetMaterialLib ();
    Material = MaterialLib->GetMaterial ( 0 );
      
    BOOLEAN IsShift;
    IsShift = Input.IsKeyDown(SC_LSHIFT) || Input.IsKeyDown(SC_RSHIFT);
    
    if (Input.IsKeyDown(SC_USCORE))
      {
        if (Material->Transparency<10-1)
          Material->Transparency++;  
      } // End else
      
    if (Input.IsKeyDown(SC_EQUAL))
      {
        if (Material->Transparency>0)
          Material->Transparency--;  
      } // End else
    
    float SpeedRatio = 1.0;
    if (IsShift)
      {
        SpeedRatio = 2.0;  
      } // End if
    
    COLLIDEDATA CollideList[5];
    FLPVECTOR3D Position,EndPt;
    FLPVECTOR3D Dir;

    Position = Camera->GetWorldPosition();
    
    if (Input.IsKeyDown(SC_RIGHT))
      {
        Camera->Rotate ( 0, -3*SpeedRatio, 0 );  
      } // End if       
    if (Input.IsKeyDown(SC_LEFT))
      {
        Camera->Rotate ( 0, 3*SpeedRatio, 0 );  
      } // End if
    if (Input.IsKeyDown(SC_UP))
      {
        Camera->Rotate ( -3*SpeedRatio, 0, 0 );  
      } // End if       
    if (Input.IsKeyDown(SC_DOWN))
      {
        Camera->Rotate ( 3*SpeedRatio, 0, 0 );  
      } // End if

    LONG CollisionCount;
      
    if (Input.IsKeyDown(SC_A))
      {
        Dir.x = 0;
        Dir.y = 0;
        Dir.z = 1*20;

        EndPt = G3D->ComputeNextPos ( Position, Camera->GetAngle(), Dir );
        CollisionCount = G3D->CheckCollision ( Position, EndPt, CollideList, 5, 1.6, 10 );
        if (CollisionCount==0)
          Camera->Move ( EndPt.x-Position.x, EndPt.y-Position.y, EndPt.z-Position.z );
      } // End if       
    if (Input.IsKeyDown(SC_Z))
      {
        Dir.x = 0;
        Dir.y = 0;
        Dir.z = -1*20;

        EndPt = G3D->ComputeNextPos ( Position, Camera->GetAngle(), Dir );  
        CollisionCount = G3D->CheckCollision ( Position, EndPt, CollideList, 5, 1.6, 10 );
        if (CollisionCount==0)
          Camera->Move ( EndPt.x-Position.x, EndPt.y-Position.y, EndPt.z-Position.z );
      } // End if

    if (FollowCamera)
      {
        Position = Camera->GetWorldPosition();
        MyLight->SetPosition ( Position.x, Position.y, Position.z );  
      } // End if
  } // End of HandleInput 
  
BOOLEAN Create3DDatabase ( G3DSYSTEM *G3D )
  {
    G3DWORLD *NewWorld;
    RGBPALETTE *LocalPal = new RGBPALETTE ();
    COLORTABLE *MatchTable = new COLORTABLE ();

    // Create World
    NewWorld = new G3DWORLD ();
    
    printf ("\n**** Creating World ****\n\n" );

    // Load Blending Color Table
    if (BlendTable->Load ( BlendFileName )==FAILURE)
      {
        printf ("Error loading Blending Table!\n" );
        exit (0);
      } // End if
    else
      {
        printf ("Blend File Loaded.\n" );
      } // End else
    G3D->SetBlendTable ( BlendTable );

    if (DoHaze)
      {
        if (HazeTable->Load ( HazeTableName )==FAILURE)
          {
            printf ("Error loading Hazing Table!\n" );
            exit (0);
          } // End if
        else
          {
            printf ("Haze File Loaded.\n" );
          } // End else
      } // End if
    else
      printf ("Haze is disabled.\n" );

    G3D->SetHazing ( DoHaze, HazeScale, HazeTable );

    // Create Light Object
    G3DLIGHT *Light;
    Light = new G3DLIGHT ();
    Light->SetName ( "Light01" );
    Light->SetPosition ( LightPosX, LightPosY, LightPosZ );
    if (ShadeTable->Load ( ShadeTableFileName )==FAILURE)
      {
        printf ("Can not load shade table! : %s\n", ShadeTableFileName );
        return FAILURE;  
      } // End if
    else
      {
        printf ("Shade File Loaded.\n" );
      } // End else

    Light->SetMaxIntensity ( LightMaxIntensity ); 
    Light->SetMinIntensity ( LightMinIntensity ); 
    Light->SetShadeTable ( ShadeTable );    
    NewWorld->AddObject ( Light );
    MyLight = Light;

    // Set Background
    RGBCOLOR BG;
    BG.Red = (BYTE)BGRed;
    BG.Green = (BYTE)BGGreen;
    BG.Blue = (BYTE)BGBlue;
    BGColor = (BYTE)((ShadeTable->GetPalette())->GetClosestColor ( BG ));
    if (BGBitMap)
      {
        if (Grafix.LoadImage ( BGFileName, BGImage, LocalPal )==FAILURE)
          {
            printf ("Can not load Background Image! : %s\n", BGFileName );
            return FAILURE;  
          } // End if
        else
          {
            printf ("Background Image Loaded.\n" );
          } // End else

        MatchTable->CopyPalette ( ShadeTable->GetPalette() );
        MatchTable->CreateMatchTable ( LocalPal );
        Grafix.ConvertImage ( BGImage, MatchTable );
      } // End if

    // Create Material Library
    G3DMATERIALLIB *MaterialLib;
    MaterialLib = new G3DMATERIALLIB ();
    MaterialLib->CreateMaterials ( 1 );
    MaterialLib->CreateTextures ( 1 );
    G3D->SetMaterialLib ( MaterialLib );

    // Add Material to this Material Library
    G3DMATERIAL *Material;
    Material = MaterialLib->GetMaterial ( 0 );
    RGBCOLOR AmbientColor;
    AmbientColor.Red = (BYTE)AmbientRed;
    AmbientColor.Green = (BYTE)AmbientGreen;
    AmbientColor.Blue = (BYTE)AmbientBlue;
    if (UseTransparent)
      Material->Attributes = MATERIAL_TRANSPARENT;
    Material->Transparency = 0;
    Material->Ambient = (ShadeTable->GetPalette())->GetClosestColor ( AmbientColor );

    // Add Texture to this Material
    if (MaterialLib->LoadTexture ( 0, TextureFileName, TextureType, ShadeTable->GetPalette() )==FAILURE)
      {
        printf ("Can not load this Texture! : %s\n", TextureFileName );
        return FAILURE;  
      } // End if
    else
      {
        printf ("Texture Loaded.\n" );
      } // End else
      
    Texture = MaterialLib->GetTexture ( 0 );
    TextureNumFrames = Texture->GetNumFrames ();
    Material->SetTexture ( Texture );
    
    // Load objects from file
    LINKEDLIST <G3DOBJECT*> *ObjectList;
    ObjectList = new LINKEDLIST<G3DOBJECT*> ();
    
    if (G3D->Load3DFile ( ObjectFileName, ObjectList, ClockWise, ScaleFactor )==FAILURE)
      {
        printf ("Can not load 3D object! : %s\n", ObjectFileName );
        return FAILURE;  
      } // End if    
    else
      {
        printf ("3D Object(s) Loaded.\n" );
      } // End else      
    
    LISTOBJECT<G3DOBJECT*> *ObjectNode;
    G3DOBJECT *Object;
    G3DPOLYHEDRON *PolyObject;
    
    ObjectNode = ObjectList->GetHead ();

    while (ObjectNode!=NULL)
      {
        Object = ObjectNode->Data;
        Object->SetMaxVisibleDistance ( MaxVisibleDistance );
        if (Object->GetObjectType()==OBJECT_TYPE_POLYHEDRON)
          {
            Object->SetPosition ( ObjPosX, ObjPosY, ObjPosZ );
            Object->SetID ( 1 );

            PolyObject = (G3DPOLYHEDRON*)Object;  
            PolyObject->SetLightSource ( Light );

            PolyObject->SetShadeFlags ( MAX_DETAIL, SHADE_GOURAUD );
            PolyObject->SetFaceFlags ( MAX_DETAIL, FACE_TEXTURE );
            
            PolyObject->SetMaterial ( Material );
            if (MapTexture)
              PolyObject->MapTexture ( U0, V0, U1, V1, U2, V2 );

            NewWorld->AddObject ( PolyObject );
            ObjectNode->Data = NULL;

            if (!LoadAll)
              break;
          } // End if
                    
        ObjectNode = ObjectNode->NextObject;              
      } // End while
       
    ObjectList->ClearAllNode ();
    delete ObjectList;
    
    delete LocalPal;
    delete MatchTable;
    
    printf ("\n**** World Is Created ****\n" );

    G3D->SetWorld ( NewWorld, TRUE );
    return SUCCESS;
  } // End of Create3DDatabase
                                                          
VOID DoBenchMark ( G3DSYSTEM *G3D )
  {
    float FrameRate1,FrameRate2;

    LONG Count;
    MYTIMER MyTimer;

    G3D->SetViewPort ( 0, 0, 319, 199 );

    FrameRate1 = FrameRate2 = 0;

    FXPPOINT2D FxpPoints[3];
    
    FxpPoints[0].x=150; FxpPoints[0].y=50;
      FxpPoints[0].u = (LONG)(U0*255*65536); FxpPoints[0].v = (LONG)(V0*255*65536);
      FxpPoints[0].I = (LONG)0; FxpPoints[0].Haze = (LONG)0;
       
    FxpPoints[1].x=50; FxpPoints[1].y=150;   
      FxpPoints[1].u = (LONG)(U1*255*65536); FxpPoints[1].v = (LONG)(V1*255*65536);
      FxpPoints[1].I = (LONG)32; FxpPoints[1].Haze = (LONG)32;
      
    FxpPoints[2].x=150; FxpPoints[2].y=150;
      FxpPoints[2].u = (LONG)(U2*255*65536); FxpPoints[2].v = (LONG)(V2*255*65536);
      FxpPoints[2].I = (LONG)63; FxpPoints[2].Haze = (LONG)63;

    MyTimer.StartTimer ();
    Count = 0;
    while (Input.IsKeyDown(SC_ESC)!=TRUE)
      {
        Count++;
        G3D->TestDrawTriangle ( FxpPoints, Texture, 63, Count, SHADE_NONE,
                                FACE_TEXTURE, NULL,
                                ShadeTable, NULL ); 
      } // End while
    MyTimer.EndTimer ();

    FrameRate1 = MyTimer.GetFrameRate ( Count );

    // Slow Version
    while (Input.IsKeyDown(SC_ESC))
      {}

    FxpPoints[0].x <<= 16;
    FxpPoints[1].x <<= 16;
    FxpPoints[2].x <<= 16;

    FxpPoints[0].I <<= 16;
    FxpPoints[1].I <<= 16;
    FxpPoints[2].I <<= 16;

    MyTimer.StartTimer ();
    Count = 0;
    while (Input.IsKeyDown(SC_ESC)!=TRUE)
      {
        Count++;
        G3D->TestDrawTriangle2 ( FxpPoints, Texture, 63, Count, SHADE_NONE,
                                 FACE_TEXTURE, NULL,
                                 ShadeTable, NULL ); 
      } // End while
    MyTimer.EndTimer ();

    FrameRate2 = MyTimer.GetFrameRate ( Count );

    Input.DeInit ();
    Grafix.ResetDisplay ();
      
    printf ( "1. Frame rate was %4.2f fps.\n", FrameRate1 );
    printf ( "2. Frame rate was %4.2f fps.\n", FrameRate2 );
    getch ();

    delete VScreen;
    delete ShadeTable;
    delete BlendTable;
    delete HazeTable;
    delete BGImage;  
  } // End of DoBenchMark
  
