Art File Format  RTCM v11-22-99

- Exportor of Doom textures towards Duke3D util by Kokak
http://perso.club-internet.fr/mryssen/DoomE.htm

With Duke3D is delivered a converter of maps Doom towards Duke. It is very well. But when one sees textures on the grounds and the walls, it is less better! The converter that I wrote, exports all textures of a Doom Wad towards a tiles0??.art of Duke3D

Tileinfo.C
=======

#include <stdio.h>
#include <stdlib.h>

void main(int argc,char **argv)
{ FILE *fp;
  long tmp;

	if (argc!=2)
	{	printf("Usage: %s <TILES????.ART>\n",argv[0]);
		exit(0);
	}
	fp=fopen(argv[1],"rb");
	fread(&tmp,4,1,fp);
	printf("ART Version: %ld\n",tmp);
	fread(&tmp,4,1,fp);	// Inutile
	fread(&tmp,4,1,fp);
	printf("First tile: %ld\n",tmp);
	fread(&tmp,4,1,fp);
	printf("Last tile: %ld\n",tmp);
	fclose(fp);
}

 

Dmtexart.C Source Code
=================

#include <stdio.h>
#include <stdlib.h>

struct TexID
{
	char TexName[9];
	long ID;
};

struct Palette
{
	unsigned char Red;
	unsigned char Green;
	unsigned char Blue;
};

unsigned char col[256];

struct Palette *ReadPaletteFromDat(char *filename)	// Cf Palette.dat (Duke)
{ FILE *fp;
  struct Palette *pal;

	if ((fp=fopen(filename,"rb"))==NULL)
	{	printf("Can't open %s\n",filename);
		exit(1);
	}
	pal=(struct Palette *)calloc(256,sizeof(struct Palette));
	fread(pal,3,256,fp);
	fclose(fp);
	return pal;
}

struct Palette *ReadPaletteFromPal(char *filename)	// Cf DEUTEX (Doom)
{ FILE *fp;
  struct Palette *pal;
  int i;

	if ((fp=fopen(filename,"rt"))==NULL)
	{	printf("Can't open %s\n",filename);
		exit(1);
	}
	pal=(struct Palette *)calloc(256,sizeof(struct Palette));
	for (i=0;i<256;i++)
		fscanf(fp,"%d %d %d",&(pal[i].Red),&(pal[i].Green),&(pal[i].Blue));
	fclose(fp);
	return pal;
}

float dist(struct Palette col1,struct Palette col2)
{ float rouge,vert,bleu;

	rouge=(float)col1.Red-(float)col2.Red;
	rouge*=rouge;
	vert=(float)col1.Green-(float)col2.Green;
	vert*=vert;
	bleu=(float)col1.Blue-(float)col2.Blue;
	bleu*=bleu;
	return(rouge+vert+bleu);
}


void DetCoul(struct Palette *pal1,struct Palette *pal2)		// Duke, Doom
{ int i,j;
  float min;

	for (i=0;i<=254;i++)
	{	min=32000;
/*		if ((pal2[i].Red==0)&&(pal2[i].Green==0)&&(pal2[i].Blue==0))
			col[i]=255;		// Transparent*/
		for (j=0;j<256;j++)
		  if (dist(pal2[i],pal1[j])<min)
		  {	min=dist(pal2[i],pal1[j]);
			col[i]=(unsigned char)j;
		  }
	}
	col[255]=255;
}

void Remplace_Coul(unsigned char *data,unsigned long size)
{ int i;

	for (i=0;i<size;i++)
		data[i]=col[data[i]];
}

void ReadTexID(FILE *fp,struct TexID *tmp)
{ char def[8];
  int i;

	fscanf(fp,"%s",def);
	for (i=0;i<9;i++) tmp->TexName[i]=0;
	fscanf(fp,"%s",tmp->TexName);
	fscanf(fp,"%ld",&(tmp->ID));
}

void main(int argc,char **argv)
{ FILE *fpS,*fpD;
  unsigned long FTile,LTile,NFTile;
  unsigned long tmp,NumTiles,NumTilesD,NLTile,*picanm;
  unsigned short *tilesizx,*tilesizy;
  unsigned char *data;
  long i;
  struct TexID *txID=(struct TexID *)malloc(sizeof(struct TexID));
  struct Palette *palDuke,*palDoom;

	if (argc!=6)
	{	printf("Usage: %s FT LT NFT Source Destination\n",argv[0]);
		printf("Where:\n");
		printf("FT: Number of the first DOOM texture in TILES000.ART generated by WAD2ART\n");
		printf("LT: Number of the last DOOM texture in TILES000.ART generated by WAD2ART\n");
		printf("NFT: Number of the first DOOM texture in the new ART file (=4000) \n");
		printf("Source: Source ART file (TILES000.ART generated by WAD2ART)\n");
		printf("Destination: Destination ART file (TILES015.ART)\n");
		printf("The names.h generated by WAD2ART must also be present in the directory\n");
		printf(" (the first line must be removed). A file names2.h will be made.\n");
		printf("This file will be the TEXTURELOOKUPS section of the TXT file for WAD2MAP)\n");
		printf("Other files required:\n");
		printf("paldoom.dat = palette.Dat generated by WAD2ART\n");
		printf("palduke.dat = original palette.Dat\n");
		exit(0);
	}
	FTile=atoi(argv[1]);
	LTile=atoi(argv[2]);

	// Palettes
	palDuke=ReadPaletteFromDat("palDuke.dat");
	palDoom=ReadPaletteFromDat("palDoom.dat");
	//palDoom=ReadPaletteFromPal("doompal.pal");
	DetCoul(palDuke,palDoom);

	NumTilesD=LTile-FTile+1;
	NFTile=atoi(argv[3]);
	NLTile=NFTile+NumTilesD-1;

	fpS=fopen(argv[4],"rb");
	fpD=fopen(argv[5],"wb");

	fread(&tmp,4,1,fpS);			// Version
	fwrite(&tmp,4,1,fpD);

	fread(&tmp,4,1,fpS);			// Inutile
	fwrite(&tmp,4,1,fpD);

	fread(&tmp,4,1,fpS);			// First tile (=0)
	fwrite(&NFTile,4,1,fpD);

	fread(&NumTiles,4,1,fpS);		// Last Tile (=number of tiles-1)
	fwrite(&NLTile,4,1,fpD);

	// Properties of the tiles...
	tilesizx=(unsigned short *)calloc(++NumTiles,2);
	tilesizy=(unsigned short *)calloc(NumTiles,2);
	picanm=(unsigned long *)calloc(NumTiles,4);
	fread(tilesizx,2,NumTiles,fpS);
	fread(tilesizy,2,NumTiles,fpS);
	fread(picanm,4,NumTiles,fpS);
	fwrite(tilesizx+FTile,2,NumTilesD,fpD);
	fwrite(tilesizy+FTile,2,NumTilesD,fpD);
	fwrite(picanm+FTile,4,NumTilesD,fpD);

	// Datas
	tmp=16+NumTiles*8;
	for (i=0;i<FTile;i++)
		tmp+=tilesizx[i]*tilesizy[i];
	fseek(fpS,tmp,SEEK_SET);

	for (i=FTile;i<NumTiles;i++)
		tmp+=tilesizx[i]*tilesizy[i];
	printf("NumTiles: %ld Size: %ld\n",NumTiles,tmp);

	for (i=0;i<NumTilesD;i++)
	{   data=(unsigned char *)malloc(tilesizx[i+FTile]*tilesizy[i+FTile]);
		fread(data,1,tilesizx[i+FTile]*tilesizy[i+FTile],fpS);
		Remplace_Coul(data,tilesizx[i+FTile]*tilesizy[i+FTile]);
		fwrite(data,1,tilesizx[i+FTile]*tilesizy[i+FTile],fpD);
		free(data);
	}

	fclose(fpS);
	fclose(fpD);

	fpS=fopen("names.h","rt");
	fpD=fopen("names2.h","wt");

	txID->ID=0;
	while (txID->ID!=FTile)
		ReadTexID(fpS,txID);

	do
	{	fprintf(fpD,"%s, %ld\n",txID->TexName,txID->ID-FTile+NFTile);
		//fprintf(fpD,"#define %s %ld\n",txID->TexName,txID->ID-FTile+NFTile);	// To view with EDITART
		ReadTexID(fpS,txID);
	}
	while (txID->ID!=LTile+1);

	fclose(fpS);
	fclose(fpD);

	free(palDuke);
	free(palDoom);
}