示例#1
0
文件: texture.c 项目: AlexMax/deutex
static void TXUdefineCurTex(char name[8],Int16 X,Int16 Y,Bool Redefn)
{  int t;
   if(TXUok!=TRUE) Bug("TXUok");
   TXUtexCur=TXUtexTop;             /*set current entry*/
   TXUtexTop+=1;                     /*find a free position*/
   if(TXUtexTop>=TXUtexMax)
   { TXUtexMax+=NEWTEXTURES;
         TXUtex=(struct TEXTUR *)Realloc(TXUtex,TXUtexMax*sizeof(struct TEXTUR));
   }
   Normalise(TXUtex[TXUtexCur].Name,name); /*declare texture*/
   TXUtex[TXUtexCur].szX=X;
   TXUtex[TXUtexCur].szY=Y;
   TXUtex[TXUtexCur].Npatches=0;
   /*check if we redefine other textures, and overide them.*/
   for(t=0;t<TXUtexCur;t++)
   { if(strncmp(TXUtex[t].Name,name,8)==0)
         { if(Redefn==TRUE)
           { TXUtex[t].Name[0]='\0';
             Detail("Warning: Texture %s is redefined\n", lump_name (name));
           }
           else /*don't redefine textures*/
           { TXUtex[TXUtexCur].Name[0]='\0';
             break;
           }
         }
   }
}
示例#2
0
文件: texture.c 项目: AlexMax/deutex
/*
** list the names of the textures defined
*/
void TXUlistTex(void)
{  Int16 t;
   if(TXUok!=TRUE) Bug("TXUok");
   for (t= 0; t <TXUtexTop; t++)
   { if(TXUtex[t].Name[0]!='\0') 
       Output("%s\n", lump_name (TXUtex[t].Name)); 
   }                                                
}
示例#3
0
文件: texture.c 项目: AlexMax/deutex
/*
** find the number of real textures
*/
static Int32 TXUrealTexture(void)
{ Int16 t;
  Int32 NbOfTex=0; /*real top of texs*/
  for(t=0; t<TXUtexTop; t++)
  { if(TXUtex[t].Npatches<1)
    { Warning("Ignored empty texture %s", lump_name (TXUtex[t].Name));
      TXUtex[t].Name[0]='\0';
    }
    if(TXUtex[t].Name[0]!='\0') NbOfTex++;
  }
  return NbOfTex;
}
示例#4
0
文件: texture.c 项目: AlexMax/deutex
/*
** read texture as text file
**
*/
void TXUreadTexFile(const char *file,Bool Redefn)
{  Int16 Pindex;
   Int16 xsize=0,ysize=0,ofsx=0,ofsy=0;
   char tname[8];  
   char pname[8];
   Int16 t,p,bit,C,b;    /*to check Xsize*/
   struct TXTFILE *TXT;
   TXT=TXTopenR(file);
/*   if(TXTbeginBloc(TXT,"TEXTURES")!=TRUE)ProgError("Invalid texture file format: %s",file);
*/
   for(t=0;t<MAXTEXTURES;t++)
   { if(TXTreadTexDef(TXT,tname,&xsize,&ysize)==FALSE) break;
     /* check X size */
     if((xsize<0)||(xsize>4096))
       ProgError("texture width out of bound");
     for(bit=1,C=0,b=0;b<16;b++,bit<<=1) if(xsize&bit) C++;
     if(C>1)
       Warning("Bogus texture %s. Width should be a power of 2",
	   lump_name (tname));
     /* check Y size */
     if((ysize<0)||(ysize>4096))
       ProgError("texture height out of bound");
     // AYM 1999-05-17
     if(ysize>509)
       Warning("Bogus texture %s. Heights above 509 are ignored",
	   lump_name (tname));
     /* declare texture */
     TXUdefineCurTex(tname,xsize,ysize, Redefn);
     for(p=0;p<MAXPATCHPERTEX;p++)
     { /* exit if no new patch to be read*/
       if(TXTreadPatchDef(TXT,pname,&ofsx,&ofsy)==FALSE) break;
       /* declare a patch wall, getting index or declaring a new index */
       Pindex=PNMgetPatchIndex(pname);
       TXUaddPatchToCurTex(Pindex,ofsx,ofsy);
     }
   }
   Phase("Read %d Textures in %s\n",t,file);
   TXTcloseR(TXT);
}
示例#5
0
void XTRgetEntry(const char *doomwad, const char *DataDir, const char *wadin,
    const char *entry, IMGTYPE Picture,SNDTYPE Sound,Bool fullSND, char trnR,
    char trnG, char trnB)
{ static struct WADINFO pwad;
  static struct WADINFO iwad;
  static char Name[8];
  Int16 e;
  char  *Entry; Int32 Entrysz;
  char  *Colors=NULL;
  Int16 insrX,insrY;
  char *extens=NULL;
  Bool Found=FALSE;

  Normalise(Name,entry);
  iwad.ok=0;
  WADRopenR(&iwad,doomwad);
   /*find PLAYPAL*/
  e=WADRfindEntry(&iwad,palette_lump);
  if(e>=0)
    Colors=WADRreadEntry(&iwad,e,&Entrysz);
  else
    ProgError("GE00", "%s: no %s lump in the iwad",
      fname (iwad.filename), lump_name (palette_lump));
  WADRclose(&iwad);
  pwad.ok=0;
  WADRopenR(&pwad,wadin);
  e=WADRfindEntry(&pwad,palette_lump);
  if(e>=0)
  {  Free(Colors);
     Colors=WADRreadEntry(&pwad,e,&Entrysz);
  }
  COLinit(trnR,trnG,trnB,Colors,(Int16)Entrysz, pwad.filename, palette_lump);
  Free(Colors);
  e=WADRfindEntry(&pwad,Name);
  if(e<0)
    ProgError("GE01", "%s: %s: lump not found",
	fname (pwad.filename), lump_name (entry));
  Phase("GE02", "%s: %s: extracting", fname (wadin), lump_name (entry));
  Entry=WADRreadEntry(&pwad,e,&Entrysz);
  /*try graphic*/
  if(Found!=TRUE)
    if(Entrysz>8)
    { switch(Picture)
      { case PICGIF: extens="GIF";break;
        case PICBMP: extens="BMP";break;
        case PICPPM: extens="PPM";break;
        case PICTGA: extens="TGA";break;
        default: Bug("GE03", "Invalid img type %d", (int) Picture);
      }
      MakeFileName(file,DataDir,"","",Name,extens);
      if(PICsaveInFile(file,PGRAPH,Entry,Entrysz,&insrX,&insrY,Picture, Name,
	  NULL) ==TRUE)
      { Info("GE04", "Picture insertion point is (%d,%d)",insrX,insrY);
        Found=TRUE;
      }
      /* FIXME try wall as well ? */
      else if((Entrysz==0x1000)||(Entrysz==0x1040))
      { if(PICsaveInFile(file,PFLAT,Entry,Entrysz,&insrX,&insrY,Picture, Name,
	  NULL) ==TRUE)
        { Found=TRUE;
        }
      }
      else if(Entrysz==64000L)
      { if(PICsaveInFile(file,PLUMP,Entry,Entrysz,&insrX,&insrY,Picture, Name,
	  NULL) ==TRUE)
        { Found=TRUE;
        }
      }
    }
  if (Found!=TRUE)
    if (peek_i16_le (Entry) == 3)
      if (Entrysz >= 8 + peek_i32_le (Entry + 4))
      { /*save as sound*/
        switch(Sound)
        { case SNDAU:  extens="AU";break;
          case SNDWAV: extens="WAV";break;
          case SNDVOC: extens="VOC";break;
          default: Bug("GE05", "Invalid snd type %d", (int) Sound);
        }
        MakeFileName(file,DataDir,"","",Name,extens);
        SNDsaveSound(file,Entry,Entrysz,Sound,fullSND, Name);
        Found=TRUE;
      }
  if(Found!=TRUE)
  { /*save as lump*/
    MakeFileName(file,DataDir,"","",Name,"LMP");
    WADRsaveEntry(&pwad,e,file);
  }
  Free(Entry);
  WADRclose(&pwad);
}
示例#6
0
/*
** extract entries from a WAD
**
** Called with cusage == NULL, (-xtract) this function extracts
** everything in the wad to separate files.
**
** Called with cusage != NULL, (-usedidx) this function creates
** no files but print statistics about which colours are used
** in the wad.
*/
void XTRextractWAD(const char *doomwad, const char *DataDir, const char
    *wadin, const char *wadinfo, IMGTYPE Picture,SNDTYPE Sound,Bool
    fullSND,NTRYB select, char trnR, char trnG, char trnB,Bool WSafe,
    cusage_t *cusage)
{ static struct WADINFO pwad;
  static struct WADINFO iwad;
  static struct WADINFO lwad;
  struct WADDIR  *pdir;
  Int16 pnb;
  ENTRY  *piden;
  Int16 p;
  Int32 ostart,osize;
  char  *buffer;
  Bool res;
  Int16 insrX=0,insrY=0;
  Bool EntryFound;
  char *extens=NULL;
  /*text file to write*/
  static struct TXTFILE *TXT = NULL;
  Phase("EX00", "Extracting entries from wad %s", wadin);
  /*open iwad,get iwad directory*/
  iwad.ok=0;
  WADRopenR(&iwad,doomwad);

  /* If -usedidx, we're only interested in graphics. */
  if (cusage != NULL)
     select &= (BGRAPHIC | BSPRITE | BPATCH | BFLAT | BSNEAP | BSNEAT | BWALL);

  /*read WAD*/
  pwad.ok=0;
  WADRopenR(&pwad,wadin);
  pdir=pwad.dir;
  pnb=(Int16)pwad.ntry;

  /*find PNAMES*/
  { Int16 pnm=WADRfindEntry(&iwad,"PNAMES");
    char *Pnam=NULL;
    Int32 Pnamsz=0;
    if(pnm<0)
      Warning("EX01", "Iwad: no PNAMES lump");
    else
      Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz);
    piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz);
    if(Pnam!=NULL)
      Free(Pnam);
  }

  /*
  ** prepare for graphics
  */

  /* Read PLAYPAL */
  {
    const char     *lumpname = palette_lump;
    struct WADINFO *wad;
    Int16           lumpnum;
    char           *lumpdata = NULL;
    Int32           lumpsz;

    wad = &pwad;
    lumpnum = WADRfindEntry (wad, lumpname);
    if (lumpnum >= 0)
      lumpdata = WADRreadEntry (wad, lumpnum, &lumpsz);
    else
    {
      wad = &iwad;
      lumpnum = WADRfindEntry (wad, lumpname);
      if (lumpnum >= 0)
	lumpdata = WADRreadEntry (wad, lumpnum, &lumpsz);
      else
      {
	long n;

	wad = NULL;
	lumpdata = Malloc (768);
	Warning ("EX02", "No %s lump found, making up a palette", lumpname);
	for (n = 0; n < 256; n++)
	{
	  lumpdata[3*n]   = n;
	  lumpdata[3*n+1] = (n & 0x7f) << 1;
	  lumpdata[3*n+2] = (n & 0x3f) << 2;
	}
      }
    }
    COLinit (trnR, trnG, trnB, lumpdata, (Int16) lumpsz,
	(wad == NULL) ? "(nofile)" : wad->filename, lumpname);
    Free (lumpdata);
  }

  /* If TITLEPAL exists, read the first 768 bytes of it. But
     don't prepare COLpal2 because we don't know yet whether we
     need it. Indeed, if there are no sneats to extract, we're
     not interested in seeing any TITLEPAL-related warnings. */
  {
    int n;
    char *titlepal_data = NULL;
    Int32 titlepal_size = 3 * NCOLOURS;

    n = WADRfindEntry (&pwad, "TITLEPAL");
    if (n >= 0)
      titlepal_data = WADRreadEntry2 (&pwad, n, &titlepal_size);
    else
    {
      n = WADRfindEntry (&iwad, "TITLEPAL");
      if (n >= 0)
	titlepal_data = WADRreadEntry2 (&iwad, n, &titlepal_size);
      else
      {
	titlepal_data = NULL;
	titlepal_size = 0;
      }
    }
    COLinitAlt (titlepal_data, titlepal_size);
  }

  /*
  ** read the PNAMES entry in PWAD
  ** or in DOOM.WAD if it does not exist elsewhere
  */
  do
  { Int16 pnm=WADRfindEntry(&pwad,"PNAMES");
    char *Pnam;
    Int32 lumpsz;
    if(pnm>=0)
      Pnam=WADRreadEntry(&pwad,pnm,&lumpsz);
    else
    { pnm=WADRfindEntry(&iwad,"PNAMES");
      if(pnm<0)
      { Warning("EX03", "Iwad: no PNAMES lump (2)");
	break;
      }
      Pnam=WADRreadEntry(&iwad,pnm,&lumpsz);
    }
    PNMinit(Pnam,lumpsz);
    Free(Pnam);
  }
  while (0);

  /*
  ** iwad not needed anymore
  */
  WADRclose(&iwad);

  /*
  ** output WAD creation directives
  ** and save entries depending on their type.
  ** If -usedidx, do _not_ create a directives file.
  */
  if (cusage != NULL)
     TXT = &TXTdummy;  /* Notional >/dev/null */ 
  else
  {
     /*check if file exists*/
     TXT=TXTopenW(wadinfo);
     {
       char comment[81];
       sprintf (comment, "DeuTex %.32s by Olivier Montanuy", deutex_version);
       TXTaddComment (TXT, comment);
     }
     TXTaddComment(TXT,"PWAD creation directives");
  }

  /*
  ** LEVELS
  */
  if(select&BLEVEL)
  { Phase("EX10", "Extracting levels...");
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { switch(piden[p]&EMASK)
      { case ELEVEL: case EMAP:
        if(EntryFound!=TRUE)
        {  MakeDir(file,DataDir,"LEVELS","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of levels");
           TXTaddSection(TXT,"levels");
           EntryFound=TRUE;
        }
        /* entries to save in WAD, named from Level name*/
	{
	  int pmax;
	  for (pmax = p; pmax < pnb && piden[pmax] == piden[p]; pmax++)
	    ;
	  res=MakeFileName(file,DataDir,"LEVELS","",pdir[p].name,"WAD");
	  if((WSafe==TRUE)&&(res==TRUE))
	    Warning("EX11", "Will not overwrite file %s",file);
	  else
	  { WADRopenW(&lwad,file,PWAD, 0);
	    ostart=WADRposition(&lwad);/*BC++ 4.5 bug*/
	    WADRdirAddEntry(&lwad,ostart,0L,pdir[p].name);
	    WADRwriteWADlevelParts (&lwad, &pwad, p, pmax - p);
	    WADRwriteDir(&lwad, 0);
	    WADRclose(&lwad);
	  }
	  TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
	  p = pmax - 1;
	}
      }
    }
  }


  /*
  ** LUMPS
  */
  if(select&BLUMP)
  { Phase("EX15", "Extracting lumps...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==ELUMP)
      { if(EntryFound!=TRUE)
        { MakeDir(file,DataDir,"LUMPS","");
	  TXTaddEmptyLine (TXT);
          TXTaddComment(TXT,"List of data Lumps");
          TXTaddSection(TXT,"lumps");
          EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
        }
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          res=FALSE;
          if(osize==64000L)/*lumps that are pics*/
          { res=XTRbmpSave(&insrX,&insrY,&pdir[p],PLUMP,DataDir,"LUMPS",&pwad,
	      Picture,WSafe, cusage);
          }
          if(res!=TRUE)   /*normal lumps*/
          { res=MakeFileName(file,DataDir,"LUMPS","",pdir[p].name,"LMP");
            if((WSafe==TRUE)&&(res==TRUE))
            {  Warning("EX16", "Will not overwrite file %s",file);
            }
            else
            { WADRsaveEntry(&pwad,p,file);
              Detail("EX17", "Saved lump as   %s", fname (file));
            }
          }
          TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
        }
      }
    }
  }

  /*
  ** TEXTURES
  */
  if(select&BTEXTUR)
  { EntryFound=FALSE;
    for(p=0;p<pnb;p++)
    { if(piden[p]==ETEXTUR+1)
      { if(EntryFound!=TRUE)
	{  MakeDir(file,DataDir,"TEXTURES","");
	   EntryFound=TRUE;
	}
	TXTaddEmptyLine (TXT);
	TXTaddComment(TXT,"List of definitions for TEXTURE1");
	TXTaddSection(TXT,"texture1");
	
	{
	   const char *name;
	   /* Always extract TEXTURES as texture1.txt ! -- AYM 1999-09-18 */
	   if (texture_lump == TL_TEXTURES)
	      name = "TEXTURE1";
	   else
	      name = pdir[p].name;
	   TXTaddEntry(TXT,name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
	   res=MakeFileName(file,DataDir,"TEXTURES","",name,"TXT");
	}
	if((WSafe==TRUE)&&(res==TRUE))
	{         Warning("EX21", "Will not overwrite file %s",file);
	}
	else
	{ buffer=(char  *)Malloc(pdir[p].size);
	  WADRseek(&pwad,pdir[p].start);
	  WADRreadBytes(&pwad,buffer,pdir[p].size);
	  TXUinit();
	  TXUreadTEXTURE(pdir[p].name, buffer, pdir[p].size, NULL, 0, TRUE);
	  Free(buffer);
	  TXUwriteTexFile(file);
	  TXUfree();
	}
      }
    }
    for(p=0;p<pnb;p++)
    { if(piden[p]==ETEXTUR+2)
      { if(EntryFound!=TRUE)
	{  MakeDir(file,DataDir,"TEXTURES","");
	   EntryFound=TRUE;
	}
	TXTaddEmptyLine (TXT);
	TXTaddComment(TXT,"List of definitions for TEXTURE2");
	TXTaddSection(TXT,"texture2");
	TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
	res=MakeFileName(file,DataDir,"TEXTURES","",pdir[p].name,"TXT");
	if((WSafe==TRUE)&&(res==TRUE))
	{         Warning("EX22", "Will not overwrite file %s",file);
	}
	else
	{ buffer=(char  *)Malloc(pdir[p].size);
	  WADRseek(&pwad,pdir[p].start);
	  WADRreadBytes(&pwad,buffer,pdir[p].size);
	  TXUinit();
	  TXUreadTEXTURE(pdir[p].name, buffer, pdir[p].size, NULL, 0, TRUE);
	  Free(buffer);
	  TXUwriteTexFile(file);
	  TXUfree();
	}
      }
    }
  }


  /*
  ** SOUNDS
  */
  if(select&BSOUND)
  { Phase("EX25", "Extracting sounds...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==ESOUND)
      { if(EntryFound!=TRUE)
        { MakeDir(file,DataDir,"SOUNDS","");
          TXTaddEmptyLine (TXT);
          TXTaddComment(TXT,"List of Sounds");
          TXTaddSection(TXT,"sounds");
          EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
        }
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          switch(piden[p])
          { case ESNDPC:
              res=MakeFileName(file,DataDir,"SOUNDS","",pdir[p].name,"TXT");
              if((WSafe==TRUE)&&(res==TRUE))
              {  Warning("EX26", "Will not overwrite file %s",file);
              }
              else
              {
		char name[33];
		strcpy(name, lump_name(pdir[p].name));
		buffer=(char  *)Malloc(pdir[p].size);
                WADRseek(&pwad,pdir[p].start);
                WADRreadBytes(&pwad,buffer,pdir[p].size);
                SNDsavePCSound(name, file, buffer, pdir[p].size);
                Free(buffer);
                Detail("EX27", "Saved PC sound as   %s", fname (file));
              }
              TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,
		  FALSE);
              break;
             case ESNDWAV:
              switch(Sound)
              { case SNDAU:  extens="AU";break;
                case SNDWAV: extens="WAV";break;
                case SNDVOC: extens="VOC";break;
                default: Bug("EX28", "Invalid snd type %d", Sound);
              }
              res=MakeFileName(file,DataDir,"SOUNDS","",pdir[p].name,extens);
              if((WSafe==TRUE)&&(res==TRUE))
              { Warning("EX29", "Will not overwrite file %s", fname (file));
              }
              else
              { buffer=(char  *)Malloc(pdir[p].size);
                WADRseek(&pwad,pdir[p].start);
                WADRreadBytes(&pwad,buffer,pdir[p].size);
                SNDsaveSound(file,buffer,pdir[p].size,Sound,fullSND,
		    pdir[p].name);
                Detail("EX30", "Saved sound as   %s", fname (file));
                Free(buffer);
              }
              TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,
		  FALSE);
              break;
            default:
              Bug("EX31", "Invalid snd type %d", piden[p]);
          }
        }
      }
    }
  }

  /*
  ** MUSICS
  */
  if(select&BMUSIC)
  { Phase("EX32", "Extracting musics...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==EMUSIC)
      { if(EntryFound!=TRUE)
        {  MakeDir(file,DataDir,"MUSICS","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of Musics");
           TXTaddSection(TXT,"musics");
           EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
        }
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          res=MakeFileName(file,DataDir,"MUSICS","",pdir[p].name,"MUS");
          if((WSafe==TRUE)&&(res==TRUE))
          {  Warning("EX33", "Will not overwrite file %s", fname (file));
          }
          else
          {
	    Detail("EX34", "Saving music as %s", fname (file));
	    WADRsaveEntry(&pwad,p,file);
          }
          TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
        }
      }
    }
  }

  /*
  ** GRAPHICS
  */
  if(select&BGRAPHIC)
  { Phase("EX35", "Extracting graphics...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==EGRAPHIC)
      { if(EntryFound!=TRUE && cusage == NULL)
        { MakeDir(file,DataDir,"GRAPHICS","");
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
        }
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          if(XTRbmpSave(&insrX,&insrY,&pdir[p],PGRAPH,DataDir,"GRAPHICS",&pwad,
	      Picture,WSafe, cusage)==TRUE)
          { if(EntryFound!=TRUE)
            { 
              TXTaddEmptyLine (TXT);
	      TXTaddComment(TXT,"List of Pictures (with insertion point)");
              TXTaddSection(TXT,"graphics");
              EntryFound=TRUE;
            }
            TXTaddEntry(TXT,pdir[p].name,NULL,insrX,insrY,FALSE,TRUE);
          }
          else if(XTRbmpSave(&insrX,&insrY,&pdir[p],PFLAT,DataDir,"LUMPS",&pwad,
	      Picture,WSafe, cusage)==TRUE)
          { /*Was saved as graphic lump*/
	    char *name = Malloc (sizeof pdir[p].name + 1);
	    sprintf (name, "%.*s", (int) sizeof pdir[p].name, pdir[p].name);
	    TXTaddComment(TXT, name);
	    Free (name);
          }
          else if (cusage == NULL)
          { if(MakeFileName(file,DataDir,"LUMPS","",pdir[p].name,"LMP")==TRUE)
            {  Warning("EX36", "Will not overwrite file %s", fname (file));
            }
            else
            { WADRsaveEntry(&pwad,p,file);
              Detail("EX37", "Saved lump as   %s", fname (file));
            }
	    {
	      char *name = Malloc (sizeof pdir[p].name + 1);
	      sprintf (name, "%.*s", (int) sizeof pdir[p].name, pdir[p].name);
	      TXTaddComment(TXT, name);
	      Free (name);
	    }
          }
        }
      }
    }
  }

  /*
  ** SPRITES
  */
  if(select&BSPRITE)
  { Phase("EX40", "Extracting sprites...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==ESPRITE)
      { if(EntryFound!=TRUE)
        {  if (cusage == NULL)
	      MakeDir(file,DataDir,"SPRITES","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of Sprites");
           TXTaddSection(TXT,"sprites");
           EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
        }
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          if(XTRbmpSave(&insrX,&insrY,&pdir[p],PSPRIT,DataDir,"SPRITES",&pwad,
	      Picture,WSafe, cusage)!=TRUE)
          { Warning("EX41", "Failed to write sprite %s",
	      lump_name (pwad.dir[p].name));
          }
          else
          { TXTaddEntry(TXT,pdir[p].name,NULL,insrX,insrY,FALSE,TRUE);
          }
        }
      }
    }
  }

  /*
  ** PATCHES
  */
  if (select & BPATCH)
  { Phase("EX45", "Extracting patches...");
    for(EntryFound=FALSE,p=0;p<pnb;p++)
     { if((piden[p] & EMASK)==EPATCH)
       { if(EntryFound!=TRUE)
         { 
	   if (cusage == NULL)
	      MakeDir(file,DataDir,"PATCHES","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of patches");
           TXTaddSection(TXT,"patches");
           EntryFound=TRUE;
         }
         if(XTRbmpSave(&insrX,&insrY,&pdir[p],PPATCH,DataDir,"PATCHES",&pwad,
	     Picture,WSafe,cusage)==TRUE)
         { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
         }
         else
         { Warning("EX46", "Failed to write patch %s",
	     lump_name (pwad.dir[p].name));
         }
       }
     }
  }

  /*
  ** PNAMES not needed anymore
  */
  PNMfree();

  /*
  ** FLATS
  */
  if (select & BFLAT)
  { Phase("EX50", "Extracting flats...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==EFLAT)
      { if(EntryFound!=TRUE)
        {  if (cusage == NULL)
	      MakeDir(file,DataDir,"FLATS","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of Floors and Ceilings");
           TXTaddSection(TXT,"flats");
           EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
	}
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          if(XTRbmpSave(&insrX,&insrY,&pdir[p],PFLAT,DataDir,"FLATS",&pwad,
	      Picture,WSafe,cusage)!=TRUE)
          { if(strncmp(pwad.dir[p].name,"F_SKY1",6)!=0)
            Warning("EX51", "Failed to write flat %s",
		lump_name (pwad.dir[p].name));
          }
          else
            TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
        }
      }
    }
  }

  /* Extract all sneaps */
  if (select & BSNEAP)
  {
    ENTRY type = ESNEAP;
    Phase ("EX55", "Extracting %s...", entry_type_plural (type));
    ostart = 0x80000000L;
    osize = 0;

    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if(piden[p] == type)
      { if(EntryFound!=TRUE)
	{
	   char comment[40];
	   if (cusage == NULL)
	      MakeDir(file,DataDir,entry_type_dir(type),"");
           TXTaddEmptyLine (TXT);
	   sprintf (comment, "List of %.20s", entry_type_plural (type));
	   TXTaddComment (TXT, comment);
	   TXTaddSection (TXT, entry_type_section (type));
	   EntryFound=TRUE;
	}
	if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
	{
	  TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
	}
	else
	{ ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
	  if(XTRbmpSave(&insrX,&insrY,&pdir[p],entry_type_pictype (type),
	      DataDir, entry_type_dir (type),&pwad, Picture, WSafe,
	      cusage) != TRUE)
	  {
	    Warning("EX56", "Failed to write %.20s %s",
		entry_type_name (type), lump_name (pwad.dir[p].name));
	  }
	  else
	  {
	    TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,
		FALSE);
	  }
	}
      }
    }
  }

  /* Extract all sneats */
  if (select & BSNEAT)
  {
    ENTRY type = ESNEAT;
    Phase ("EX60", "Extracting %s...", entry_type_plural (type));
    ostart = 0x80000000L;
    osize = 0;

    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if(piden[p] == type)
      { if(EntryFound!=TRUE)
	{
	   char comment[40];
	   if (cusage == NULL)
	      MakeDir(file,DataDir,entry_type_dir(type),"");
           TXTaddEmptyLine (TXT);
	   sprintf (comment, "List of %.20s", entry_type_plural (type));
	   TXTaddComment (TXT, comment);
	   TXTaddSection (TXT, entry_type_section (type));
	   EntryFound=TRUE;
	}
	if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
	{
	  TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
	}
	else
	{ ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
	  if(XTRbmpSave(&insrX,&insrY,&pdir[p],entry_type_pictype (type),
	      DataDir, entry_type_dir (type),&pwad, Picture, WSafe,
	      cusage) != TRUE)
	  {
	    Warning("EX61", "Failed to write %.20s %s",
		entry_type_name (type), lump_name (pwad.dir[p].name));
	  }
	  else
	  {
	    TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,
		FALSE);
	  }
	}
      }
    }
  }

  /* Extract all Strife scripts */
  if (select & BSCRIPT)
  {
    ENTRY type = ESSCRIPT;
    Phase ("EX65", "Extracting %s...", entry_type_plural (type));
    ostart = 0x80000000L;
    osize = 0;

    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if(piden[p] == type)
      { if(EntryFound!=TRUE)
	{
	   char comment[40];
	   if (cusage == NULL)
	      MakeDir(file,DataDir,entry_type_dir(type),"");
           TXTaddEmptyLine (TXT);
	   sprintf (comment, "List of %.20s", entry_type_plural (type));
	   TXTaddComment (TXT, comment);
	   TXTaddSection (TXT, entry_type_section (type));
	   EntryFound=TRUE;
	}
	if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
	{
	  TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
	}
	else
	{ ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
	  { res = MakeFileName (file, DataDir, entry_type_dir(type), "",
	      pdir[p].name, "txt");
            if (WSafe==TRUE && res==TRUE)
            {  Warning("EX66", "Will not overwrite file %s",file);
            }
            else
            { if (sscript_save (&pwad, p, file))
	      {
		Warning("EX67", "Failed to write %.20s %s",
		  entry_type_name (type), lump_name (pwad.dir[p].name));
	      }
	      else
	      {
		TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,
		FALSE);
	      }
            }
          }
	}
      }
    }
  }

  /* Extract all ROTT walls. They're raw 64x64 bitmaps, between
     WALLSTRT and WALLSTOP. This is based on the regular Doom
     flats extraction code above. */
  if (ROTT && (select & BWALL))
  { Phase("EX70", "Extracting walls...");
    ostart=0x80000000L;osize=0;
    for(EntryFound=FALSE,p=0;p<pnb;p++)
    { if((piden[p]&EMASK)==EWALL)
      { if(EntryFound!=TRUE)
        {  if (cusage == NULL)
	      MakeDir(file,DataDir,"WALLS","");
           TXTaddEmptyLine (TXT);
           TXTaddComment(TXT,"List of walls");
           TXTaddSection(TXT,"walls");
           EntryFound=TRUE;
        }
        if((ostart==pwad.dir[p].start)&&(osize==pwad.dir[p].size))
        { TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,TRUE,FALSE);
	}
        else
        { ostart=pwad.dir[p].start; osize=pwad.dir[p].size;
          if(XTRbmpSave(&insrX,&insrY,&pdir[p],PWALL,DataDir,"WALLS",&pwad,
	      Picture,WSafe,cusage)!=TRUE)
	    Warning("EX71", "Failed to write wall %s",
		lump_name (pwad.dir[p].name));
          else
            TXTaddEntry(TXT,pdir[p].name,NULL,INVALIDINT,INVALIDINT,FALSE,FALSE);
        }
      }
    }
  }


  /* If -usedidx, print statistics */
  if (cusage != NULL)
  {
    int n;

    printf ("Npixels    Idx  Nlumps  First lump\n");
    printf ("---------  ---  ------  ----------\n");
    for (n = 0; n < NCOLOURS; n++)
      printf ("%9lu  %3d  %5lu   %s\n",
	  cusage->uses[n],
	  n,
	  cusage->nlumps[n],
	  (cusage->uses[n] == 0) ? "" : lump_name (cusage->where_first[n]));
    putchar ('\n');
  }

  /*
  ** exit graphics and end
  */
  COLfree();
  Free(piden);
  WADRclose(&pwad);
  TXTaddEmptyLine (TXT);
  TXTaddComment(TXT,"End of extraction");
  TXTcloseW(TXT);
  Phase("EX99", "End of extraction");
}
示例#7
0
文件: texture.c 项目: AlexMax/deutex
Bool TXUcheckTex(Int16 npatch,Int16  *PszX)
{  Int16 t,tt,p,pat,col,top,found;
   Int16 bit,C,b;        /*bit test*/
   Int16 Meduza;
   Bool Res=TRUE;
   if(TXUok!=TRUE) Bug("TXUok");
   Output("Checking textures\n");
   if(TXUtexTop<1) Bug("TxuNTx");
   if(TXUtexTop<100) Output("Warning: Some textures could be missing! (less than 100 defined)\n");
   for(pat=0, t=0; t<TXUtexTop; t++)
   { if(TXUtex[t].Npatches<1)
     { Output("Warning: Texture %s is empty\n", lump_name (TXUtex[t].Name));
       Res=FALSE;
     }
     top=pat+TXUtex[t].Npatches;
     if(top>TXUpatTop) Bug("TxuP>D");
     /*
     ** check width
     */
     for(bit=1,C=0,b=0;b<16;b++,bit<<=1) if((TXUtex[t].szX)&bit) C++;
     if(C>1)
     { Output("Warning: Width of %s is not a power of 2\n",
	 lump_name (TXUtex[t].Name));
       Res=FALSE;
     }
     /*
     ** check height
     */
     if(TXUtex[t].szY>128)
     { Output("Warning: Height of %s is more than 128\n",
	 lump_name (TXUtex[t].Name));
       Res=FALSE;
     }
     /*
     ** check patch for:
     ** - void columns            (crashes the game at boot)
     ** - possible meduza effect  (if the patch is used on 2S walls)
     */
     Meduza=0;
     for(col=0;col<TXUtex[t].szX;col++)
     { if(Meduza<2)Meduza=0; /*no Meduza effect found yet*/
       found=FALSE;
       for(p=0; p<(TXUtex[t].Npatches); p++)
       { if(TXUpat[pat+p].Pindex>=npatch)
             Bug("~TxuP>D");
         if(col>=TXUpat[pat+p].ofsX)
         { top=PszX[TXUpat[pat+p].Pindex]+TXUpat[pat+p].ofsX;
           if(col<top)
           { found=TRUE;
             if(Meduza>=2)
               break; /*two patches on same column. Meduza effect*/
             else
               Meduza++; /*keep looking for patches*/
           }
         }
       }
       if(found==FALSE)
       { Output("Warning: Empty column %d in texture %s\n",
	   col, lump_name (TXUtex[t].Name));
         Res=FALSE;
       }
     }
     if(Meduza>=2)  /*there is a colum with two patches*/
     { Output("Warning: Texture %s should not be used on a two sided wall.\n",
	 lump_name (TXUtex[t].Name));
     }
     pat+=TXUtex[t].Npatches;
   }
   /*
   ** check duplication
   */
   for(t=0; t<TXUtexTop; t++)
   { for(tt=t+1;tt<TXUtexTop;tt++)
       if(strncmp(TXUtex[t].Name,TXUtex[tt].Name,8)==0)
       { Output("Warning: texture %s is duplicated\n",
	   lump_name (TXUtex[t].Name));
         Res=FALSE;
       }
   }
   return Res;
}
示例#8
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);
    }
  }
}
示例#9
0
/*
 *      sscript_save - save a script lump to file
 */
int sscript_save(struct WADINFO *wad, int16_t n, const char *file)
{
    FILE *fp = NULL;
    unsigned char *data = NULL;
    int32_t size = 0;
    const char *lumpname = wad->dir[n].name;

    data = (unsigned char *) WADRreadEntry(wad, n, &size);
    if (size % PAGESZ) {
        Warning("SS10", "script %s: weird size %ld", lump_name(lumpname),
                (long) size);
        size = PAGESZ * (size / PAGESZ);
    }
    fp = fopen(file, "w");
    if (fp == NULL) {
        nf_err("SS15", "%s: %s", file, strerror(errno));
        return 1;
    }
    fprintf(fp, "# DeuTex Strife script source version 1\n");
    /* Save all pages */
    {
        int p;
        for (p = 0; p < size / PAGESZ; p++) {
            unsigned long ofs = PAGESZ * p;
            int o;

            fputc('\n', fp);
            fprintf(fp, "page %d {\n", p);
            dump_field(fp, data, &ofs, FT_I32, "    unknown0   ");
            dump_field(fp, data, &ofs, FT_I32, "    unknown1   ");
            dump_field(fp, data, &ofs, FT_I32, "    unknown2   ");
            dump_field(fp, data, &ofs, FT_I32, "    unknown3   ");
            dump_field(fp, data, &ofs, FT_I32, "    unknown4   ");
            dump_field(fp, data, &ofs, FT_I32, "    unknown5   ");
            dump_field(fp, data, &ofs, FT_S16, "    character  ");
            dump_field(fp, data, &ofs, FT_NAME, "    voice      ");
            dump_field(fp, data, &ofs, FT_NAME, "    background ");
            dump_field(fp, data, &ofs, FT_S320, "    statement  ");

            for (o = 0; o < 5; o++) {
                /* If the option is zeroed out, omit it */
                if (mem_is_zero((char *) (data + ofs), OPTIONSZ)) {
                    ofs += OPTIONSZ;
                    continue;
                }

                /* Else, decode it */
                fputc('\n', fp);
                fprintf(fp, "    option %d {\n", o);
                dump_field(fp, data, &ofs, FT_I32, "        whata   ");
                dump_field(fp, data, &ofs, FT_I32, "        whatb   ");
                dump_field(fp, data, &ofs, FT_I32, "        whatc   ");
                dump_field(fp, data, &ofs, FT_I32, "        whatd   ");
                dump_field(fp, data, &ofs, FT_I32, "        whate   ");
                dump_field(fp, data, &ofs, FT_I32, "        price   ");
                dump_field(fp, data, &ofs, FT_I32, "        whatg   ");
                dump_field(fp, data, &ofs, FT_S32, "        option  ");
                dump_field(fp, data, &ofs, FT_S80, "        success ");
                dump_field(fp, data, &ofs, FT_I32, "        whath   ");
                dump_field(fp, data, &ofs, FT_I32, "        whati   ");
                dump_field(fp, data, &ofs, FT_S80, "        failure ");
                fputs("    }\n", fp);
            }

            fputs("}\n", fp);
            /* Sanity check */
            if (ofs % PAGESZ)
                Bug("SS20", "script %s: page %d: bad script offset %d",
                    lump_name(lumpname), p, (int) ofs);
        }
    }

    free(data);
    if (fclose(fp)) {
        nf_err("SS45", "%s: %s", file, strerror(errno));
        return 1;
    }
    return 0;
}
示例#10
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);
}