示例#1
0
文件: texture.c 项目: AlexMax/deutex
/*
**
** convert raw data (as read from wad) into Textures
** Data= texture entry
** if PatchSz>0, Patch defines the patch list
*/
void TXUreadTEXTURE(char  *Data,Int32 DataSz,char  *Patch, Int32 PatchSz,Bool Redefn)
{ Int32 Pos,  Numtex, Numpat, dummy;
  /* texture data*/
  Int16 t,p,i, Xsize, Ysize; /* size x and y  */
  /* nb of wall patches used to build it */
  /* wall patch inside a texture */
  Int16 Xofs, Yofs,Pindex;         /* x,y coordinate in texture space*/
  /* patch name index in PNAMES table */
  Int32  MaxPindex;
  static char tname[8];     /*texture name*/
  static char pname[8];     /*patch name*/
  size_t header_size;
  size_t item_size;
  int    have_texture_name;
  int    have_header_dummies;

  if (input_texture_format == TF_NAMELESS)
  {
    header_size         = 14;
    item_size           = 10;
    have_texture_name   = 0;
    have_header_dummies = 1;
  }
  else if (input_texture_format == TF_NONE)
  {
    Warning ("No texture definitions to read.");
    return;  /* FIXME is it OK to do that ? */
  }
  else if (input_texture_format == TF_NORMAL)
  {
    header_size         = 22;
    item_size           = 10;
    have_texture_name   = 1;
    have_header_dummies = 1;
  }
  else if (input_texture_format == TF_STRIFE11)
  {
    header_size         = 18;
    item_size           = 6;
    have_texture_name   = 1;
    have_header_dummies = 0;
  }
  else
  {
    Bug ("TXUreadTEXTURE: bad itf %d", (int) input_texture_format);
  }

  /*get number of patches*/
  if(PatchSz>0)
  { MaxPindex = peek_i32_le (Patch);
    dummy=4L+(MaxPindex*8L);
    if(dummy>PatchSz) ProgError("Bad PNAMES format");
  }
  else
  { MaxPindex = PNMgetNbOfPatch();
  }
  if((MaxPindex<0)||(MaxPindex>0x7FFF)) ProgError("Bad PNAMES entry");
  /*get number of textures*/
  Numtex = peek_i32_le (Data);
  if(Numtex<0) ProgError("Bad TEXTURE entry");
  if(Numtex>MAXTEXTURES) ProgError("Too many TEXTUREs");

  /*read textures*/
  for (t = 0; t <Numtex; t++)
  { Pos = peek_i32_le (Data + 4L + t * 4L);
    if (Pos + header_size > DataSz)
      ProgError("TEXTURE entry too small");

    if (have_texture_name)
    {
      Normalise (tname, Data + Pos);
      Pos += 8;
    }
    else  /* No name. Make one up (TEXnnnn)*/
    {
      if (t > 9999)
      {
	Warning ("More than 10000 textures. Ignoring excess.");
        break;
      }
      sprintf (tname, "TEX%04d", (int) t);
    }

    Pos += 4;  /* Skip 2 dummy unused fields */

    Xsize = peek_i16_le (Data + Pos);
    Pos += 2;
    if((Xsize<0)||(Xsize>4096))
      ProgError ("Texture %s: width out of bound (%d)",
	  lump_name (tname), (int) Xsize);

    Ysize = peek_i16_le (Data + Pos);
    Pos += 2;
    if((Ysize<0)||(Ysize>4096))
      ProgError ("Texture %s: height out of bound (%d)",
	  lump_name (tname), (int) Ysize);

    if (have_header_dummies)
      Pos += 4;  /* Skip 2 dummy unused fields */

    Numpat = peek_i16_le (Data + Pos)&0xFFFF;
    Pos += 2;
    if((Numpat<0)||(Numpat>MAXPATCHPERTEX))
      ProgError("Texture %s: too many patches (%d)",
	  lump_name (tname), (int) Numpat);

    /* declare texture */
    TXUdefineCurTex(tname,Xsize,Ysize,Redefn);
    if (Pos + (long) Numpat * item_size > DataSz)
      ProgError("TEXTURE entry too small");
    for (p = 0; p < Numpat; p++, Pos += item_size)
    {
      Xofs = peek_i16_le (Data + Pos);
      if((Xofs<-4096)||(Xofs>4096))
	ProgError("Texture %s(%d/%d): bad patch X-offset %d",
	    lump_name (tname), (int) p, (int) Numpat, (int) Xofs);
      Yofs = peek_i16_le (Data + Pos + 2);
      if((Yofs<-4096)||(Yofs>4096))
	ProgError("Texture %s(%d/%d): bad patch Y-offset %d",
	    lump_name (tname), (int) p, (int) Numpat, (int) Yofs);
      Pindex = peek_i16_le (Data + Pos + 4);
      if((Pindex<0)||(Pindex>MaxPindex))
	ProgError("Texture %s(%d/%d): bad patch index %d",
	    lump_name (tname), (int) p, (int) Numpat, (int) Pindex);
      /*if new patch list, recalculate Pindex*/
      if(PatchSz>0)
      { for(dummy=(4L+(Pindex*8L)),i=0;i<8;i++)
          pname[i]=Patch[dummy+i];
        Pindex=PNMgetPatchIndex(pname);
      }
      /*declare patch*/
      TXUaddPatchToCurTex(Pindex,Xofs,Yofs);
    }
  }
}
示例#2
0
void CMPOmakePWAD(const char *doomwad,WADTYPE type, const char *PWADname,
		     const char *DataDir, const char *texin, NTRYB select,
		     char trnR, char trnG, char trnB, Bool George)
{  /*
   ** type PWAD as we are generating a real PWAD
   */
   Int32 start=0, size=0;
   static char name[8];
   static char filenam[8];
   /*PNAMES */
   Int16  nbPatchs,p;
   Bool NeedPNAME=FALSE;
   Bool FoundOne=FALSE;
   Bool Repeat;
   IMGTYPE Picture;
   /*optional insertion point*/
   Int16 X,Y;
   /*text file to read*/
   static struct TXTFILE *TXT;
   /*DOOM wad*/
   static struct WADINFO iwad,pwad;
   /*result wad file*/
   static struct WADINFO rwad;
   /*for Pnames*/
   Int16 entry;char  *EntryP;Int32 EntrySz=0;
   /* initialisation*/

   Info("CM01", "Composing %cWAD %s from %s",
       (type==IWAD) ? 'I' : 'P', fname (PWADname), texin);

   /*open iwad,get iwad directory*/
   iwad.ok=0;
   WADRopenR(&iwad,doomwad);

   TXT= TXTopenR(texin, 0);
   WADRopenW(&rwad,PWADname,type, 1); 		/* fake IWAD or real PWAD */
   /*
   ** dirty: set error handler to delete the wad out file,
   ** if an error occurs.
   */
   CMPOrwad = &rwad;
   CMPOwadout = PWADname;
   ProgErrorAction(CMPOerrorAction);
   /*
   ** levels! add your own new levels to DOOM!
   ** read level from a PWAD file
   */
   if(select&BLEVEL)
   {  if(TXTseekSection(TXT,"LEVELS"))
      { while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ p=IDENTlevel(name);
	  if(p<0) ProgError("CM11", "Illegal level name %s", lump_name (name));
	  if(MakeFileName(file,DataDir,"LEVELS","",filenam,"WAD")!=TRUE)
		ProgError("CM12", "Can't find level WAD %s", fname (file));
	  Detail("CM13", "Reading level WAD file %s", fname (file));
	  WADRwriteWADlevel(&rwad,file,name);
	}
      }
   }
   /*
   ** prepare palette for graphics
   */
   /*find PLAYPAL*/
   if(select&(BGRAPHIC|BSPRITE|BPATCH|BFLAT))
   {
     /* If wadinfo.txt mentions a custom PLAYPAL, use that.
        Otherwise, use the one in the iwad. */
     char *paldata = NULL;
     const char *playpal_pathname = NULL;
     const char *playpal_lumpname = NULL;

     if (TXTseekSection (TXT, "LUMPS"))
     {
       while (TXTentryParse(name, filenam, &X, &Y, &Repeat, TXT, FALSE) == TRUE)
       {
	 if (strcmp (name, "PLAYPAL") == 0)
	 {
	   FILE *playpal_fp;

	   MakeFileName (file, DataDir, "LUMPS", "", filenam, "LMP");
	   playpal_pathname = file;
	   playpal_lumpname = NULL;
	   EntrySz = 768;
	   paldata = Malloc (EntrySz);
	   playpal_fp = fopen (file, FOPEN_RB);
	   if (playpal_fp == NULL)
	     ProgError ("CM21", "%s: %s", fname (file), strerror (errno));
	   EntrySz = fread (paldata, 1, EntrySz, playpal_fp);
	   if (EntrySz != 768)
	     /* DEBUG was ProgError */
	     Warning ("CM22", "%s: short read", fname (file));
	   fclose (playpal_fp);
	   break;
	 }
       }
     }
     if (paldata == NULL)
     {
       playpal_pathname = iwad.filename;
       playpal_lumpname = palette_lump;
       entry = WADRfindEntry(&iwad, palette_lump);
       if (entry < 0)
	 ProgError ("CM23", "Can't find %s in main WAD",
	     lump_name (palette_lump));
       paldata = WADRreadEntry (&iwad, entry, &EntrySz);
     }
     COLinit (trnR, trnG, trnB, paldata, (Int16) EntrySz, playpal_pathname,
	 playpal_lumpname);
     Free (paldata);
   }

   /*
   **
   **   lumps. non graphic raw data for DOOM
   */
   if(select&BLUMP)
   {  start=size=0;
      if(TXTseekSection(TXT,"LUMPS"))
      { Phase("CM30", "Making lumps");
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{  if(Repeat!=TRUE)
	   { WADRalign4(&rwad);     /*align entry on Int32 word*/
	     start=WADRposition(&rwad);
	     if(MakeFileName(file,DataDir,"LUMPS","",filenam,"LMP")==TRUE)
	     { size=WADRwriteLump(&rwad,file);
	     }
	     else
	     { Picture=CMPOloadPic(&size,&rwad,file,DataDir,"LUMPS",name,
		 filenam,PLUMP,X,Y);
	       if(Picture==PICNONE)
		 if(CMPOcopyFromWAD(&size,&rwad,DataDir,"LUMPS",name,filenam)
		     !=TRUE)
		   ProgError("CM31", "Can't find lump or picture file %s",file);
	     }
	   }
	   WADRdirAddEntry(&rwad,start,size,name);
	}
      }
   }
   /*
   ** initialise list of patch names
   */
   if(select&(BTEXTUR|BPATCH))
   { entry=WADRfindEntry(&iwad,"PNAMES");
     if(entry<0) ProgError("CM40", "Can't find PNAMES in main WAD");
     EntryP=WADRreadEntry(&iwad,entry,&EntrySz);
     PNMinit(EntryP,EntrySz);
     Free(EntryP);
     NeedPNAME = FALSE;
   }
   /*
   ** read texture1
   */
   if(select&BTEXTUR)
   {  if(TXTseekSection(TXT,"TEXTURE1"))
      { Phase("CM50", "Making TEXTURE1");
	TXUinit();
	entry=WADRfindEntry(&iwad,"TEXTURE1");
	if(entry>=0)
	{ EntryP=WADRreadEntry(&iwad,entry,&EntrySz);
	  TXUreadTEXTURE("TEXTURE1", EntryP, EntrySz, NULL, 0, TRUE);
	  Free(EntryP);
	}
	else Warning("CM51", "Can't find TEXTURE1 in main WAD");
	FoundOne=FALSE;
	 /*read TEXTURES composing TEXTURE1*/
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ if(MakeFileName(file,DataDir,"TEXTURES","",name,"TXT")==TRUE)
	  { Detail("CM52", "Reading texture file %s", fname (file));
	    TXUreadTexFile(file,TRUE);
	    NeedPNAME=TRUE;
	    FoundOne=TRUE;
	  }
	  else if(MakeFileName(file,DataDir,"TEXTURES","",name,"WAD")==TRUE)
	  { Detail("CM53", "Reading texture WAD %s", fname (file));
	    WADRopenR(&pwad,file);
	    entry=WADRfindEntry(&pwad,"TEXTURE1");
	    if(entry>=0)
	    { EntryP=WADRreadEntry(&pwad,entry,&EntrySz);
	      TXUreadTEXTURE("TEXTURE1", EntryP, EntrySz, NULL, 0, TRUE);
	      Free(EntryP);
	      NeedPNAME=TRUE;
	      FoundOne=TRUE;
	    }
	    WADRclose(&pwad);
	  }
	  else
	    ProgError("CM54", "Can't find texture list %s", file);
	}
	/*write texture*/
	if(FoundOne==TRUE)
	{ WADRalign4(&rwad);     /*align entry on Int32 word*/
	  start= WADRposition(&rwad);
	  size = TXUwriteTEXTUREtoWAD(&rwad);
	  WADRdirAddEntry(&rwad,start,size,"TEXTURE1");
	}
	TXUfree();
      }
   }
   /*
   ** read texture2
   */
   if(select&BTEXTUR)
   {  if(TXTseekSection(TXT,"TEXTURE2"))
      { Phase("CM55", "Making TEXTURE2");
	TXUinit();
	entry=WADRfindEntry(&iwad,"TEXTURE2");
	if(entry>=0)
	{ EntryP=WADRreadEntry(&iwad,entry,&EntrySz);
	  TXUreadTEXTURE("TEXTURE2", EntryP, EntrySz, NULL, 0, TRUE);
	  Free(EntryP);
	}
	else Warning("CM56", "Can't find TEXTURE2 in main WAD");
	FoundOne=FALSE;
	 /*read TEXTURES composing TEXTURE2*/
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ if(MakeFileName(file,DataDir,"TEXTURES","",name,"TXT")==TRUE)
	  { Detail("CM57", "Reading texture file %s", fname (file));
	    TXUreadTexFile(file,TRUE);
	    NeedPNAME=TRUE;
	    FoundOne=TRUE;
	  }
	  else if(MakeFileName(file,DataDir,"TEXTURES","",name,"WAD")==TRUE)
	  { Detail("CM58", "Reading texture WAD %s", fname (file));
	    WADRopenR(&pwad,file);
	    entry=WADRfindEntry(&pwad,"TEXTURE2");
	    if(entry>=0)
	    { EntryP=WADRreadEntry(&pwad,entry,&EntrySz);
	      TXUreadTEXTURE("TEXTURE2", EntryP, EntrySz, NULL, 0, TRUE);
	      Free(EntryP);
	      NeedPNAME=TRUE;
	      FoundOne=TRUE;
	    }
	    WADRclose(&pwad);
	  }
	  else
	    ProgError("CM59", "Can't find texture list %s", file);
	}
	/*write texture*/
	if(FoundOne==TRUE)
	{ WADRalign4(&rwad);     /*align entry on Int32 word*/
	  start= WADRposition(&rwad);
	  size = TXUwriteTEXTUREtoWAD(&rwad);
	  WADRdirAddEntry(&rwad,start,size,"TEXTURE2");
	}
	TXUfree();
      }
   }
   /*
   ** PNAME
   */
   if(select&BTEXTUR)
   {  if(NeedPNAME)    /*write PNAME in PWAD*/
      { /*write entry PNAME*/
	Phase("CM41", "Making PNAMES");
	WADRalign4(&rwad);     /*align entry on Int32 word*/
	start=WADRposition(&rwad);
	size =PNMwritePNAMEtoWAD(&rwad);
	WADRdirAddEntry(&rwad,start,size,"PNAMES");
      }
   }
   /*
   **
   **   sounds. all sounds entries
   */
   if(select&BSOUND)
   {  start=size=0;
      if(TXTseekSection(TXT,"SOUNDS"))
      { Phase("CM60", "Making sounds");
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ if(Repeat!=TRUE)
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"TXT")==TRUE)
	    { size=SNDcopyPCSoundInWAD(&rwad,file);
	      Detail("CM62", "Reading PC sound from file %s", fname (file));
	    }
	    else
	    { if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"WAV")==TRUE)
	      { size=SNDcopyInWAD(&rwad,file,SNDWAV);
	      }
	      else if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"AU")==TRUE)
	      { size=SNDcopyInWAD(&rwad,file,SNDAU);
	      }
	      else if(MakeFileName(file,DataDir,"SOUNDS","",filenam,"VOC")==TRUE)
	      { size=SNDcopyInWAD(&rwad,file,SNDVOC);
	      }
	      else if(CMPOcopyFromWAD(&size,&rwad,DataDir,"SOUNDS",name,
		    filenam)!=TRUE)
		ProgError("CM63", "Can't find sound %s, AU or WAV or VOC",file);
	      Detail("CM64", "Reading sound file %s", fname (file));
	    }
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
      }
   }
   /*
   **
   **   Musics
   */
   if(select&BMUSIC)
   {  start=size=0;
      if(TXTseekSection(TXT,"MUSICS"))
      { Phase("CM65", "Making musics");
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ if(Repeat!=TRUE)
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    /*Music*/
	    if(MakeFileName(file,DataDir,"MUSICS","",filenam,"MUS")==TRUE)
	    { size=WADRwriteLump(&rwad,file);
	      Detail("CM66", "Reading music file %s", fname (file));
	    }
	    else if(CMPOcopyFromWAD(&size,&rwad,DataDir,"MUSICS",name,
		  filenam)!=TRUE)
	      ProgError("CM67", "Can't find music %s",file);
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
      }
   }
   /*
   **  ordinary graphics
   */
   if(select&BGRAPHIC)
   {  start=size=0;
      if(TXTseekSection(TXT,"GRAPHICS"))
      { Phase("CM70", "Making graphics");
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE)
	{ if(Repeat!=TRUE)
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    Picture=CMPOloadPic(&size,&rwad,file,DataDir,"GRAPHICS",name,
		filenam,PGRAPH,X,Y);
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
      }
   }
   /*
   **  SS_START
   **  sprites
   **  SS_END
   */
   if(select&BSPRITE)
   {  start=size=0;
      if(TXTseekSection(TXT,"SPRITES"))
      { Phase("CM75", "Making sprites");
	FoundOne=FALSE;
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE)
	{ /* first sprite seen? */
	  if((Repeat!=TRUE)||(FoundOne!=TRUE))
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    if(FoundOne!=TRUE)
	    { if(type==IWAD)
		WADRdirAddEntry(&rwad,start,0L,"S_START");
	      else
		WADRdirAddEntry(&rwad,start,0L,"SS_START");
	    }
	    FoundOne=TRUE;
	    CMPOloadPic(&size,&rwad,file,DataDir,"SPRITES",name,
		filenam,PSPRIT,X,Y);
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
	if(FoundOne==TRUE)
	{ WADRalign4(&rwad);
	  start=WADRposition(&rwad);
	  if((type==IWAD)||(George==TRUE))
	    WADRdirAddEntry(&rwad,start,0L,"S_END");
	  else
	    WADRdirAddEntry(&rwad,start,0L,"SS_END");
	}
      }
   }
   /*
   ** Try to load patches
   **   even if no new textures (old patches could be redefined)
   */
   /* write new patches  in PWAD*/
   /* read the name of the new textures and insert them*/
   /* between P_START and P_END for future completion*/

   if(select&BPATCH)
   {  FoundOne=FALSE;
      /*
      ** First look for patches in [PATCHES]
      */
      start=size=0;
      if(TXTseekSection(TXT,"PATCHES"))
      { Phase("CM80", "Making patches");
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE)==TRUE)
	{ if((Repeat!=TRUE)||(FoundOne!=TRUE))
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    if(FoundOne==FALSE)
	    { if(type==IWAD)
	      {
		WADRdirAddEntry(&rwad,start,0L,"P_START");
		WADRdirAddEntry(&rwad,start,0L,"P1_START");
	      }
	      else
	      {
		WADRdirAddEntry(&rwad,start,0L,"PP_START");
	      }
	    }
	    FoundOne=TRUE;
	    CMPOloadPic(&size,&rwad,file,DataDir,"PATCHES",name,
		filenam,PPATCH,X,Y);
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
      }
      /*
      ** Check if all the needed patches are defined.
      */
      nbPatchs=PNMgetNbOfPatch();
      for(p=0;p<nbPatchs;p++)
      {
	if(PNMisNew(p)!=TRUE)
	{
	  continue;/*if old patch, forget it*/
	}
	PNMgetPatchName(name,p);
        Normalise(filenam,name);
	/*search in main IWAD directory*/
	if(WADRfindEntry(&iwad,name)>=0)
	{ Output("Reusing DOOM entry %s as patch\n", lump_name (name));
	}
	/*search in current PWAD*/
	else if(WADRfindEntry(&rwad,name)<0)
	{ /*PATCH not found in current WAD, load automatically
	  **from the PATCH directory
	  */
	  WADRalign4(&rwad);     /*align entry on Int32 word*/
	  start=WADRposition(&rwad);
	  Picture=CMPOloadPic(&size,&rwad,file,DataDir,"PATCHES",name,
	      filenam,PPATCH,INVALIDINT,INVALIDINT);
	  if(Picture!=PICNONE)
	  { if(FoundOne==FALSE)
	    { Phase("CM82", "Making patches");
	      if(type==IWAD)
	      { WADRdirAddEntry(&rwad,start,0L,"P_START");
		WADRdirAddEntry(&rwad,start,0L,"P1_START");
	      }
	      else
		WADRdirAddEntry(&rwad,start,0L,"PP_START");
	    }
	    FoundOne=TRUE;
	    WADRdirAddEntry(&rwad,start,size,name);
	  }
	}
      }
      if(FoundOne==TRUE)
      { WADRalign4(&rwad);     /*align entry on Int32 word*/
	start=WADRposition(&rwad);
	if(type==IWAD)
	{ WADRdirAddEntry(&rwad,start,0L,"P1_END");
	  WADRdirAddEntry(&rwad,start,0L,"P2_START");
	  WADRdirAddEntry(&rwad,start,0L,"P2_END");
	  WADRdirAddEntry(&rwad,start,0L,"P3_START");
	  WADRdirAddEntry(&rwad,start,0L,"P3_END");
	  WADRdirAddEntry(&rwad,start,0L,"P_END");
	}
	else
	  WADRdirAddEntry(&rwad,start,0L,"PP_END");
      }
   }
   /*
   ** clear off Pnames
   */
   if(select&(BTEXTUR|BPATCH))
   { PNMfree();
   }
   /*  FF_START
   **  Flats
   **  F_END   AYM 1998-12-22 (was FF_END)
   */
   if(select&BFLAT)
   {  if(TXTseekSection(TXT,"FLATS"))
      { Phase("CM85", "Making flats");
	FoundOne=FALSE;
	while(TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,FALSE)==TRUE)
	{ if((Repeat!=TRUE)||(FoundOne!=TRUE))
	  { WADRalign4(&rwad);     /*align entry on Int32 word*/
	    start=WADRposition(&rwad);
	    if(FoundOne==FALSE)
	    { if(type==IWAD)
	      { WADRdirAddEntry(&rwad,start,0L,"F_START");
		WADRdirAddEntry(&rwad,start,0L,"F1_START");
	      }
	      else
		WADRdirAddEntry(&rwad,start,0L,"FF_START");
	    }
	    FoundOne=TRUE;
	    CMPOloadPic(&size,&rwad,file,DataDir,"FLATS",name,
		filenam,PFLAT,INVALIDINT,INVALIDINT);
	  }
	  WADRdirAddEntry(&rwad,start,size,name);
	}
	if(FoundOne==TRUE)
	{ start=WADRposition(&rwad);
	  if(type==IWAD)
	  { WADRdirAddEntry(&rwad,start,0L,"F1_END");
	    WADRdirAddEntry(&rwad,start,0L,"F2_START");
	    WADRdirAddEntry(&rwad,start,0L,"F2_END");
	    WADRdirAddEntry(&rwad,start,0L,"F3_START");
	    WADRdirAddEntry(&rwad,start,0L,"F3_END");
	    WADRdirAddEntry(&rwad,start,0L,"F_END");
	  }
	  else
	    WADRdirAddEntry(&rwad,start,0L,"F_END");  /* AYM 1998-12-22 */
	}
      }
   }
   /*
   ** exit from graphic
   */
   if(select&(BGRAPHIC|BSPRITE|BPATCH|BFLAT)) COLfree();
   /*
   ** iwad not needed anymore
   */
   WADRclose(&iwad);
   /*
   ** the end
   */
   TXTcloseR(TXT);
   WADRwriteDir(&rwad, 1);  /* write the WAD directory */
   ProgErrorCancel();
   WADRclose(&rwad);
   /*add some junk at end of wad file, for DEU 5.21*/
   if(type==PWAD)  AddSomeJunk(PWADname);
}