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

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

/*

PRO File Checker

Makes sure all the textures and shadetables are present, and
looks for faces with invalid texture coordinates

 Revision History:
 November 5, 1997: Created

*/

PR_OBJECT *object;

void CheckTextures (void)
{
PR_DWORD i;

  for (i = 0; i < PR_NumTextures; i++)
    if ((PR_WorldTextures[i].filename != NULL) &&
        (PR_WorldTextures[i].image == NULL))
      {
       printf ("%s texture was not found\n", PR_WorldTextures[i].filename);
      }
}

void CheckTables (void)
{
PR_DWORD i;

  for (i = 0; i < PR_NumTables; i++)
    if ((PR_ShadeTables[i].name != NULL) &&
        (PR_ShadeTables[i].table == NULL))
      {
       printf ("%s table was not found\n", PR_ShadeTables[i].name);
      }
}



typedef struct {
  PR_WORD wireframe;
  PR_WORD texture;
  PR_WORD wrapping_texture;
  PR_WORD xray_texture;
  PR_WORD low_res_texture;
  PR_WORD perspective_texture;
  PR_WORD translucent;
  PR_WORD lighted;
  PR_WORD gouraud_shaded;
  PR_WORD dummy1;
  PR_WORD dummy2;
} PR_MethodStruct;

extern PR_MethodStruct PR_MethodInfo[100];

PR_DWORD IsWrappingMethod (method)
{
  return (PR_MethodInfo[method].wrapping_texture);
}



PR_DWORD CheckUV (PR_FACE *face)
{
PR_MATERIAL *mat;
PR_DWORD method;
PR_DWORD texw, texh;
PR_DWORD wrapping;
PR_DWORD i, result;

  result = 0;
  mat = &PR_ObjectMaterialList[face->material];
  method = mat->render_method;
  wrapping = IsWrappingMethod (method);
  texw = PR_WorldTextures[mat->texture_number].width;
  texh = PR_WorldTextures[mat->texture_number].height;

  if (wrapping)
    {
     if ((texw != 256) || (texh != 256))
        result |= 1;
    }
  else  /* Non wrapping.. check the UV coordinates */
    {
     texw <<= 16;
     texh <<= 16;

     for (i = 0; i < 3; i++)
       {
        if ((face->face_data.u[i] < 0) ||
            (face->face_data.u[i] > texw) ||
            (face->face_data.v[i] < 0) ||
            (face->face_data.v[i] > texh))
          result |= 2;
       }
    }

  return result;
}


void CheckFaces (void)
{
PR_DWORD segnum;
PR_DWORD facenum;
PR_SEGMENT *seg;
PR_FACE *face;
PR_DWORD result, endresult;

  endresult = 0;

  for (segnum = 0; segnum < object->num_segments; segnum++)
    {
     seg = &object->segment_list[segnum];

     for (facenum = 0; facenum < seg->num_faces; facenum++)
       {
        face = &seg->face_list[facenum];
        result = CheckUV (face);
        if (result != 0)
          endresult |= result;
       }
    }

  if (endresult & 1)
    {
     printf ("A texture has been used with a wrapping method but it is \n");
     printf ("not a 256x256 image. This will cause problems with software rendering.\n");
    }

  if (endresult & 2)
    {
     printf ("A texture has been used with a non-wrapping method but texture coordinates\n");
     printf ("have been wrapped. This will cause problems with software rendering.\n");
    }

}



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


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

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

  PR_Initialize (50);

  PR_DetectVGA();
  PR_InitializeVGA ();

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

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

  wsetmode (3);

  CheckTextures ();
  CheckTables ();
  CheckFaces ();
  printf ("done\n");
}



