/* RETEX v1.0. Part of DoomTex, by Steve McCrea 26/8/94 */
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <malloc.h>
#include <fcntl.h>

int	fh;
FILE	*fp;

void error(char *errstr)
{	printf("\nRetex: ");
	printf(errstr);
	exit(1);	}

main(argc,argv)
int argc;
char *argv[];
{
	char texname[10], patname[10], nearnam[10];
	char *pnames, *pnam;
	char *texgarb, *texg;
	long *offsets, *offs;
	long numtexs, numpats, onumpats, lnumpats, i;
	int patnum, x, y, j, k;
	
	if (argc != 5)
		error("Usage: retex <textfile> <old pnames> <new pnames> <textures>\n");

	texname[8]='\0';
	patname[8]='\0';
	nearnam[8]='\0';
	
	if (!(fp=fopen(argv[1], "rt")))
		error("Can't open <textfile>.\n");
	if ((pnames=(char *)malloc(8192))==NULL)
		error("Can't allocate 8K for pnames.\n");
	if ((texgarb=(char *)malloc(32768))==NULL)
		error("Can't allocate 32K for textures.\n");
	if ((offsets=(long *)malloc(8192))==NULL)
		error("Can't allocate 8K for offsets.\n");
	if (!(fh=open(argv[2], O_BINARY|O_RDONLY)))
		error("Can't open the <old pnames> resource.\n");
	read(fh, &numpats, 4);
	onumpats=numpats;
	if (read(fh, pnames, 8*numpats)!=8*numpats)
		error("The <old pnames> resource is short.\n");
	for (i=0; i<8*numpats; i++)
		if (*(pnames+i)>0x40 && *(pnames+i)<0x5b) *(pnames+i) |= 0x20;
	pnam=pnames;
	texg=texgarb;
	offs=offsets;
	numtexs=0;
	lnumpats=0;

// Skip to the textures

	if (fscanf(fp, "%s", texname)==EOF)
		error("End of <textfile> before TEXTURES found.\n");
	while (strcmp(texname, "TEXTURES"))
		if (fscanf(fp, "%s", texname)==EOF)
			error("End of <textfile> before TEXTURES found.\n");
	for (k=0; k<8; k++) nearnam[k]=texname[k];

// Loop thru textures

	numtexs=0;
	if (fscanf(fp, "%s", texname)==EOF)
		error("End of <textfile> before EOF found.\n");
	while (strcmp(texname, "EOF")) {
		if (texname[0]<0x41 || texname[0]>0x5a) {
			printf("\nRetex: After %8s: %8s not a valid texture or patch name.\n", nearnam, texname);
			exit(1);
			}
		for (k=0; k<8; k++) nearnam[k]=texname[k];
		numtexs++;
		*offs++=texg-texgarb;
		for (k=0;k<8;k++) *(texg++)=texname[k];
		*((long *)texg)=0; texg+=4;
		fscanf(fp, "%d %d", &x, &y);
		if (x<1 || x>1024) {
			printf("\nRetex: Texture %8s x value %d out of range.\n", texname, x);
			exit(1);
			}
		i=1; j=0; for (k=0; k<11; k++) { i *= 2; if (i==x) j=1; }
		if (j==0) printf("\nWarning: Texture %8s x value %d is not a power of 2.\n", texname, x);
		*((int *)texg)=x; texg+=2;
		if (y<1 || y>128) {
			printf("\nRetex: Texture %8s y value %d out of range.\n", texname, y);
			exit(1);
			}
		*((int *)texg)=y; texg+=2;
		*((long *)texg)=0; texg+=6;
		if (fscanf(fp, "%s", patname)==EOF)
			error("File truncated.\n");
		lnumpats=0;
		while (patname[0]>0x60 && patname[0]<0x7b) {
			lnumpats++;
			i=0; j=0;
			while (j<100 && i<numpats) {
				k=0; while (k<9) if (patname[k++]==0) break;
				k--;
				if (strncmp(patname, pnames+8*i, 8) == 0)
					j=100;
				i++;
				}
			if (j==100)
				patnum=i-1;
			else {
				patnum=numpats++;
				for (k=0; k<8; k++)
					*(pnames+8*patnum+k)=patname[k];
				}
			fscanf(fp, "%d %d", &x, &y);
			if (x<-1024 || y<-512 || x>1024 || y>512) {
				printf("\nRetex: Patch %8s out of bounds.\n", patname);
				exit(1);
				}
			*((int *)texg)=x; texg+=2;
			*((int *)texg)=y; texg+=2;
			*((int *)texg)=patnum; texg+=2;
			*((long *)texg)=0x00000001; texg+=4;
			if (fscanf(fp, "%s", patname)==EOF)
				error("End of <textfile> before EOF found.\n");
			}
		if (lnumpats==0) {
			printf("\nRetex: Texture %8s without a patch.\n", texname);
			exit(1);
			}
		*((int *)(texg-10*lnumpats-2))=lnumpats;
		for (k=0; k<8; k++) texname[k]=patname[k];
		printf("#");
		}
	switch (numpats-onumpats) {
		case 0:	{
			printf("\nNo new patches.\n");
			break;
			}
		default: {
			printf("\n%d new patches:\n", numpats-onumpats);
			j=0;
			for (i=onumpats; i<numpats; i++) {
				for (k=0; k<8; k++) patname[k]=*(pnames+8*i+k);
				printf("%8s", patname);
				if (++j==7) {j=0; printf("\n"); }
					else printf("  ");
				}
			}
		}
	offs=offsets;
	for (i=0; i<numtexs; i++)
		*offs++ += 4*numtexs+4;

	if (!(fh=open(argv[3], O_CREAT|O_BINARY|O_WRONLY, S_IREAD|S_IWRITE)))
		error("Can't create <pnames> resource.\n");
	write(fh, &numpats, 4);
	if (write(fh, pnames, 8*numpats) != 8*numpats)
		error("No space to write <pnames>.\n");
	close(fh);
	if (!(fh=open(argv[4], O_CREAT|O_BINARY|O_WRONLY, S_IREAD|S_IWRITE)))
		error("Can't create <texture> resource.\n");
	write(fh, &numtexs, 4);
	write(fh, offsets, 4*numtexs);
	if (write(fh, texgarb, texg-texgarb) != texg-texgarb)
		error("No space to write <textures>.\n");
	close(fh);

	free(pnames);
	free(texgarb);
	
	exit(0);
}