#include <stdlib.h>
#include <direct.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>

#include <pr.h>
#include <prgui.h>

#ifdef __3DFX__
#include <glide.h>
#include <pr3dfx.h>
#endif

#ifdef WIN32
#include <windows.h>
#endif

/* Power Render Phong Enhancement

   Description:  Takes an input PRO file, and doubles the number of
                 faces.  The second set of faces is set to a new material
                 which is used for a translucent phong environment map.

                 After using this utility, you must edit the PRO file with
                 editmat and set the environment map texture to an
                 appropriate phong map.

  (modified from JOINPRO)
*/


char outfile[80];               /* Name of the output file */
PR_OBJECT *object1;
PR_DWORD choice;

PR_MATERIAL phong;
PR_DWORD phong_num;             /* Number of phong material */
PR_DWORD texnum;
PR_DWORD device;


void InitializeDevices (void)
{
#ifdef __MYST__
  if ((device == DEVICE_MYSTIQUE) || (device == DEVICE_ANY))
    device = PR_DetectMystique ();
#endif

#ifdef __3DFX__
  if ((device == DEVICE_3DFX) || (device == DEVICE_ANY))
    device = PR_Detect3Dfx ();
#endif

#if !defined (MSGLIDE) && !defined (WTGLIDE)
  #if defined (MSDD) || defined (WTDD)
    if ((device == DEVICE_D3D) || (device == DEVICE_ANY))
      device = PR_DetectD3D ();   /* Attempt to find the device */
  #endif

  if ((device == DEVICE_SVGA) || (device == DEVICE_ANY))
    device = PR_DetectSVGA ();   /* Attempt to find the device */

  if ((device == DEVICE_VGA) || (device == DEVICE_ANY))
    device = PR_DetectVGA ();   /* Attempt to find the device */
#endif

#ifdef __MYST__
  if (device == DEVICE_MYSTIQUE)
    {
     PR_InitializeMystique ();
     atexit (PR_ShutdownMystique);
    }
#endif

#ifdef __3DFX__
  if (device == DEVICE_3DFX)
    {
     PR_Initialize3Dfx ();
     atexit (PR_Shutdown3Dfx);
    }
#endif

#if !defined (MSGLIDE) && !defined (WTGLIDE)
  #if defined (MSDD) || defined (WTDD)
  if (device == DEVICE_D3D)
    {
     PR_InitializeD3D ();
     atexit (PR_ShutdownD3D);
    }
  #endif
  if (device == DEVICE_SVGA)
    {
     PR_InitializeSVGA ();
     atexit (PR_ShutdownSVGA);
    }
  else if (device == DEVICE_VGA)
    {
     PR_InitializeVGA ();
     atexit (PR_ShutdownVGA);
    }
#endif
}


void MakePhongMaterial (void)
{
  PR_SetMaterialBaseColor       (&phong, 0);
  PR_SetMaterialColor           (&phong, 255, 255, 255);
  PR_SetMaterialAlpha			(&phong, 255);
  PR_SetMaterialEnvironmentAxis (&phong, ZAXIS);
  PR_SetMaterialEnvironmentMap  (&phong, TRUE);
  PR_SetMaterialMethod          (&phong, T_LIGHTMAP_ADD);
  PR_SetMaterialMipMap          (&phong, MIP_LEVEL1, 0);
  PR_SetMaterialMipMap          (&phong, MIP_LEVEL2, 0);
  PR_SetMaterialMipMap          (&phong, MIP_LEVEL3, 0);
  PR_SetMaterialMipMap          (&phong, MIP_LEVEL4, 0);
  PR_SetMaterialMipMapShift     (&phong, MIP_LEVEL1, 1);
  PR_SetMaterialMipMapShift     (&phong, MIP_LEVEL2, 2);
  PR_SetMaterialMipMapShift     (&phong, MIP_LEVEL3, 3);
  PR_SetMaterialMipMapShift     (&phong, MIP_LEVEL4, 4);
  PR_SetMaterialMipMapState     (&phong, FALSE);
  PR_SetMaterialName            (&phong, "Phong Map");
  PR_SetMaterialShades          (&phong, 32);
  PR_SetMaterialTable           (&phong, 0);
  PR_SetMaterialTexture         (&phong, texnum);

  phong_num = PR_AddMaterial (&phong);
}


void ApplyPhong (PR_OBJECT *obj)
{
PR_FACE *oldlist;
PR_DWORD seg;
PR_DWORD face;
PR_FACE *newface;

  for (seg = 0; seg < obj->num_segments; seg++)
    {
     oldlist = obj->segment_list[seg].face_list;
     obj->segment_list[seg].face_list = malloc (sizeof (PR_FACE) *
                obj->segment_list[seg].num_faces * 2);

     obj->segment_list[seg].flags |= FLAG_NORMALS;

     for (face = 0; face < obj->segment_list[seg].num_faces; face++)
       {
        newface = &obj->segment_list[seg].face_list[face];
        memcpy (newface, &oldlist[face], sizeof (PR_FACE));
       }

     for (face = 0; face < obj->segment_list[seg].num_faces; face++)
       {
        newface = &obj->segment_list[seg].face_list[face +
                   obj->segment_list[seg].num_faces];
        memcpy (newface, &oldlist[face], sizeof (PR_FACE));
        newface->material = phong_num;
        newface->backmaterial = phong_num;
       }
     obj->segment_list[seg].num_faces *= 2;
    }
}




void main (int argc, char *argv[])
{
  PRGUI_InitPath (argv[0]);

  if (argc < 2)
    {
	 PR_FatalError (
                "PHONG Utility    version "
                PR_VERSION_NUMBER
                "\nCopyright 1997 Egerter Software\n\n"
		"Usage: \n"
		"PHONG file1.PRO outfile.PRO\n", "PHONG");
    }

  printf ("PHONG Utility    version ");
  printf (PR_VERSION_NUMBER);
  printf ("\nCopyright 1997 Egerter Software\n\n");

  if (PRGUI_FileExists (argv[2]))
    {
     #ifdef WIN32
     if (MessageBox(NULL, "The file already exists! Overwrite?\n",
                 "PHONG", MB_OKCANCEL) != IDOK)
		exit (1);
	 #else
     printf ("%s already exists! Overwrite? (Y/N)\n",
            argv[2]);
     do {
       choice = toupper (getch ());
     } while (choice != 'N' && choice != 'Y');

     if (choice == 'N')
       exit (1);
	 #endif
    }


#if defined (MSGLIDE) || defined (WTGLIDE)
  device = DEVICE_3DFX;
#else
  device = DEVICE_SVGA;
#endif

  PR_Initialize (50);
  InitializeDevices ();


  PR_AllocMaterials (512);
  PR_AllocShadeTables (32);
  PR_AllocTextures (255);

  PR_SetTextureFormat (TEXTURE_NORMAL);

  object1 = PR_LoadPRO (argv[1], LOAD_NORMAL);
  if (object1 == NULL)
    PR_FatalError ("An error has occurred when loading the file.\n", "PHONG");

  texnum = PR_LoadTexture ("phong.pcx");

  MakePhongMaterial ();
  ApplyPhong (object1);
   
  PR_SavePRO (argv[2], object1, SAVE_ALL_MATERIALS);
}




