void *ReallocMemory (void *old, long size) { #if 0 void *ptr; if (size < 1) size = 1; ptr = realloc(old,size); if (NULL == ptr) ProgError ("Out of memory! (cannot reallocate %lu bytes)", size); return ptr; #else void *ret; // DEBUG // ULONG asksize = size; /* limit fragmentation on large blocks */ if (size >= (ULONG) SIZE_THRESHOLD) size = (size + (ULONG) SIZE_OF_BLOCK) & ~((ULONG) SIZE_OF_BLOCK); // TRACE ("Realloc: ask size = " << dec << asksize << ", real size = " << size << " bytes"); #ifdef __WIN32__ ret = realloc (old, size); #else ret = farrealloc (old, size); #endif if (ret == NULL) ProgError ("Out of memory! (cannot reallocate %lu bytes)", size); return ret; #endif }
/* ** Output and Error handling */ static Bool asFile=FALSE; static Int16 Verbosity=2; static FILE *Stdout; /*command output*/ static FILE *Stderr; /*errors*/ static FILE *Stdwarn; /*warningss*/ static FILE *Stdinfo; /*infos*/ void PrintInit(Bool asfile) { #if DT_OS == 'o' setbuf(stdout,(char *)NULL); #endif /*clear a previous call*/ PrintExit(); /* choose */ if(asfile==TRUE) { if((Stdout=fopen("output.txt",FOPEN_WT))==NULL) ProgError("Can't open output.txt"); if((Stderr=fopen("error.txt",FOPEN_WT))==NULL) { Stderr=stderr; ProgError("Can't open error.txt"); } Stdinfo=stdout; Stdwarn=Stderr; } else { Stdout=stdout; Stderr=stderr; Stdwarn=stderr; Stdinfo=stdout; } asFile=asfile; }
/*read string, skip space before, stop space/\n*/ static bool TXTread(struct TXTFILE *TXT, char name[8], int16_t valid) { int16_t c = 0, val = 0, n = 0; while (1) { if (!TXTgetc(TXT, &c, &val)) return false; if (val & NEWLINE) continue; if (val & SPACE) continue; if (val & valid) break; ProgError("TR11", "%s(%ld): illegal char %s", TXT->pathname, (long) TXT->Lines, quotechar(c)); } name[0] = (char) c; for (n = 1; n < 256; n++) { if (!TXTgetc(TXT, &c, &val)) break; if (val & SPACE) { TXTungetc(TXT); break; } if (!(val & valid)) ProgError("TR13", "%s(%ld): illegal char %s in word", TXT->pathname, (long) TXT->Lines, quotechar(c)); if (n < 8) name[n] = (char) c; } if (n < 8) name[n] = '\0'; return true; }
void PNMinit(char *buffer,Int32 size) { Int16 n,i; char picname[8]; Int32 pnames; /*find the number of entries in PNAME*/ pnames=0; if(size>4L) { pnames = peek_i32_le (buffer); if(pnames>0x7FFFL) ProgError("Too many patches"); if(size<(4L+8L*pnames)) ProgError("Wrong size of PNAMES entry"); } /*initialise*/ PNMmax=(Int16)(pnames+NEWPATCHS); PNMpatchs=(struct PNMP *)Malloc(PNMmax*sizeof(struct PNMP)); PNMtop=(Int16)pnames; PNMknown=0; /*Read patches*/ if(pnames<=0)return; for(n=0;n<PNMtop;n++) { for(i=0;i<8;i++)picname[i]=buffer[4L+8L*n+i]; Normalise(PNMpatchs[n].name,picname); } PNMknown=PNMtop; PNMok=TRUE; }
void *AllocMemory (long size) { #if 0 void *ptr; if (size < 1) size = 1; ptr = malloc(size); if (NULL == ptr) ProgError ("Out of memory (cannot allocate %lu bytes)", size); else memset(ptr,0,size); return ptr; #else void *ret; // DEBUG // ULONG asksize = size; // limit fragmentation on large blocks if (size >= (ULONG) SIZE_THRESHOLD) size = (size + (ULONG) SIZE_OF_BLOCK) & ~((ULONG) SIZE_OF_BLOCK); // TRACE ("Alloc: ask size = " << dec << asksize ", real size = " << size << " bytes"); #ifdef __WIN32__ ret = malloc (size); #else ret = farmalloc (size); #endif if (ret == NULL) ProgError ("Out of memory (cannot allocate %lu bytes)", size); #ifdef __WIN32__ memset (ret, 0, size); #else BYTE HUGE *ptr = (BYTE *)ret; while ( size > UINT_MAX ) { memset (ptr, 0, UINT_MAX); ptr += UINT_MAX; size -= UINT_MAX; } memset (ptr, 0, (size_t)size); #endif return ret; #endif }
/* ** write texture as text file */ void TXUwriteTexFile(const char *file) { Int16 t,p,pat,top; char pname[8]; FILE *out; if(TXUok!=TRUE) Bug("TXUok"); if(TXUtexTop<1) Bug("TxunTx"); out=fopen(file,FOPEN_WT); if(out==NULL) ProgError("Can't write file %s\n",file); TXUrealTexture(); fprintf(out,";Format of textures:\n"); fprintf(out,";TextureName\tWidth\tHeight\n"); fprintf(out,";*\tPatchName\tXoffset\tYoffset\n"); for (pat=0, t= 0; t <TXUtexTop; t++) { if(TXUtex[t].Name[0]!='\0') /*if tex was not redefined*/ { fprintf(out,"%-8.8s ",TXUtex[t].Name); fprintf(out,"\t\t%d\t%d\n",TXUtex[t].szX,TXUtex[t].szY); for (p = 0; p < TXUtex[t].Npatches; p++) { top=pat+p; if(top>=TXUpatTop) Bug("TxuP>D"); PNMgetPatchName(pname,TXUpat[pat+p].Pindex); fprintf(out,"*\t%-8.8s ",pname); fprintf(out,"\t%d\t%d\n",TXUpat[pat+p].ofsX,TXUpat[pat+p].ofsY); } } pat+=TXUtex[t].Npatches; } fprintf(out,";End\n"); fclose(out); }
static INLINE void *GetMemory( size_t size) { void *ret = malloc( size); if (!ret) ProgError( "out of memory (cannot allocate %u bytes)", size); return ret; }
static INLINE void *ResizeMemory( void *old, size_t size) { void *ret = realloc( old, size); if (!ret) ProgError( "out of memory (cannot reallocate %u bytes)", size); return ret; }
struct TXTFILE *TXTopenR(const char *file, int silent) { struct TXTFILE *TXT; size_t pathname_len; /*characters */ if (!TXTok) TXTinit(); pathname_len = strlen(file); TXT = (struct TXTFILE *) Malloc(sizeof(struct TXTFILE) + pathname_len); /*some inits */ strcpy(TXT->pathname, file); TXT->Lines = 1; /*start in line 1 */ TXT->SectionStart = 0; TXT->SectionEnd = 0; TXT->fp = fopen(file, FOPEN_RT); if (TXT->fp == NULL) { if (silent) { free(TXT); return NULL; } ProgError("TR03", "%s: %s", fname(file), strerror(errno)); } return TXT; }
/* ** Read integer if exist before NEWLINE, ** but don't eat NEWLINE */ static Int16 TXTreadOptionalShort(struct TXTFILE *TXT) { static char name[9]; Int16 n,c=0,val=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE)return INVALIDINT; if(!(val & NEWLINE)) { if(val & SPACE) continue; /*skip space*/ if(val & STEQUAL) continue; /*skip '='*/ if(val & NUMBER) break; /*look for number*/ } TXTungetc(TXT); return INVALIDINT; /*not a number. abort*/ } name[0]=(char)c; for(n=1; n<256; n++ ) { if(TXTgetc(TXT,&c,&val)!=TRUE) break; if(val&NEWLINE) {TXTungetc(TXT);break;} if(val&SPACE)break; if(!(val&NUMBER)) ProgError("TR42", "%s(%ld): illegal char %s in number", fname (TXT->pathname), (long) TXT->Lines, quotechar (c)); if(n<8) name[n]=(char)c; } if(n<8)name[n]='\0'; name[8]='\0'; return (Int16)atoi(name); }
/* ** For any Writing of text files */ struct TXTFILE *TXTopenW(const char *file) { /*open, and init if needed */ struct TXTFILE *TXT; size_t pathname_len; /*characters */ if (!TXTok) TXTinit(); pathname_len = strlen(file); TXT = (struct TXTFILE *) Malloc(sizeof(struct TXTFILE) + pathname_len); /*some inits */ strcpy(TXT->pathname, file); TXT->Lines = 1; /*start in line 1 */ TXT->SectionStart = 0; TXT->SectionEnd = 0; TXT->fp = fopen(file, FOPEN_RT); if (TXT->fp == NULL) { TXT->fp = fopen(file, FOPEN_WT); } else { fclose(TXT->fp); TXT->fp = fopen(file, FOPEN_AT); Warning("TW03", "%s: already exists, appending to it", fname(file)); } if (TXT->fp == NULL) ProgError("TW05", "%s: %s", fname(file), strerror(errno)); return TXT; }
/* **TXTentryParse(name,filenam,&X,&Y,&Repeat,TXT,TRUE) */ Bool TXTentryParse(char *name,char *filenam,Int16 *x,Int16 *y,Bool *repeat, struct TXTFILE *TXT, Bool XY) { Int16 c=0,val=0; Bool comment; Int16 xx=INVALIDINT,yy=INVALIDINT; if(TXTreadIdent(TXT,name)!=TRUE) return FALSE; /* skip the equal*/ if(TXTgetc(TXT,&c,&val)!=TRUE) return FALSE; if(c!='=') TXTungetc(TXT); /* read integer*/ if(XY==TRUE) { xx=TXTreadOptionalShort(TXT); yy=TXTreadOptionalShort(TXT); } Normalise(filenam,name); TXTreadOptionalName(TXT,filenam); if(XY==TRUE) { if(xx==INVALIDINT) xx=TXTreadOptionalShort(TXT); if(yy==INVALIDINT) yy=TXTreadOptionalShort(TXT); } *repeat= TXTreadOptionalRepeat(TXT); *x=xx; *y=yy; for(comment=FALSE;;) { if(TXTgetc(TXT,&c,&val)!=TRUE)break; if(val & NEWLINE) break; if(val & COMMENT) /*eat commentaries*/ { comment=TRUE; continue;} if(val & SPACE) /*eat space*/ { continue;} if(comment==FALSE) ProgError("TR87", "%s(%ld): bad entry format", fname (TXT->pathname), (long) TXT->Lines); } return TRUE; }
/* the main program "loop" (inherited from 'dmpsmu.c') */ void MainLoop() { if (VerbLine) Verbose = TRUE; if (GameVersion == 2) { Episode = 0; if (Mission < 1 || Mission > 32) ProgError( "invalid or missing game mission number (%d)", Mission); } else /* GameVersion != 2 */ if (!(GameVersion == 17 && Episode == 4 && Mission == 1)) /* Heretic E4M1 */ { if (Episode < 1 || Episode > (GameVersion == 4 ? 4 : (GameVersion & 1 ? 3 : 1))) ProgError( "invalid or missing game episode number (%d)", Episode); if (Mission < 1 || Mission > 9) ProgError( "invalid or missing game mission number (%d)", Mission); } if (TxFlName == NULL || strcmp(TxFlName, "-") == 0) { TxFlName = "standard output"; TxFile = stdout; } if (!InclTexts && !InclFlats) ProgError( "All Texture lists disabled"); if (GameVersion == 2) printf( "\nOutputting Textures list of level MAP%02d to \"%s\".\n", Mission, TxFlName); else printf( "\nOutputting Textures list of level E%dM%d to \"%s\".\n", Episode, Mission, TxFlName); if(!TxFile) { if ((TxFile = fopen( TxFlName, "wt")) == NULL) ProgError( "error opening output file \"%s\"", TxFlName); } fprintf( TxFile, "# WADTXLS: WAD TeXture LiSter, ver %s\n", WADTXLS_VERSION); ListLevel( Episode, Mission); fprintf( TxFile, "# End of file.\n"); fclose( TxFile); if (GameVersion == 0) printf("Remember to register your copy of DOOM!\n"); else if (GameVersion == 16) printf("Remember to register your copy of Heretic!\n"); }
/************** merge PWAD IWAD directory module ****************/ void ADDallSpriteFloor(const char *wadout, const char *doomwad, const char *wadres,NTRYB select) { struct WADINFO iwad; struct WADINFO pwad; struct WADINFO rwad; Int16 n; ENTRY *iiden; /*identify entry in IWAD*/ ENTRY *piden; /*identify entry in PWAD*/ Int32 start,size,ostart,osize; Int16 pnm;char *Pnam;Int32 Pnamsz; struct WADDIR *NewDir;Int32 NewNtry; Phase("ME88", "Copying sprites and/or flats"); Phase("ME88", " from iwad %s", fname (doomwad)); Phase("ME88", " and pwad %s", fname (wadres)); Phase("ME88", " into pwad %s", fname (wadout)); /* get iwad directory, and identify */ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("ME91", "Can't find PNAMES in main WAD"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); /* identify iwad*/ iiden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,TRUE); /* get pwad directory, and identify*/ pwad.ok=0; WADRopenR(&pwad,wadres); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); /**/ Free(Pnam); /*where to put pwad? at pwadstart*/ if((iwad.maxpos|pwad.maxpos)&EXTERNAL )Bug("ME94", "AddExt"); /* merge the two directories */ NewDir=LISmergeDir(&NewNtry,TRUE,TRUE,select,&iwad,iiden,EXTERNAL,&pwad,piden,0); /* create a new PWAD*/ rwad.ok=0; WADRopenW(&rwad,wadout,PWAD, 1); for(n=0;n<NewNtry;n++) { ostart=NewDir[n].start; osize=NewDir[n].size; WADRalign4(&rwad); start=WADRposition(&rwad); if(ostart&EXTERNAL) size=WADRwriteWADbytes(&rwad,&iwad,ostart&(~EXTERNAL),osize); else size=WADRwriteWADbytes(&rwad,&pwad,ostart,osize); WADRdirAddEntry(&rwad,start,size,NewDir[n].name); } Free(NewDir); /*close files memory*/ WADRclose(&iwad); WADRclose(&pwad); WADRwriteDir(&rwad, 1); WADRclose(&rwad); Phase("ME98", "Addition of sprites and floors is complete"); }
static void AddSomeJunk(const char *file) { FILE *out;Int16 n; out=fopen(file,FOPEN_AB); /*open R/W at the end*/ if(out==NULL) ProgError("CM97", "%s: %s", fname (file), strerror (errno)); for(n=0;n<HowMuchJunk;n++) if(fwrite(Junk,1,64,out)<64) Warning("CM98", "Can't insert my junk!"); fclose(out); }
/* ** Reallocate memory */ void *Realloc (void *old, long size) { void *ret; if(size<1) { Warning("Attempt to allocate %ld bytes",size); size=1; } #if DT_OS == 'd' && DT_CC == 'b' ret = farrealloc( old, size); #else if ((size_t) size != size) ProgError ("Tried to realloc %ld b but couldn't." " Use another compiler.", size); ret = realloc( old, (size_t)size); #endif if (ret==NULL) ProgError( "Out of memory (Needed %ld bytes)", size); return ret; }
/* actually, this is (size - 1) */ void *Malloc (long size) { void *ret; if(size<1) { Warning("MM02", "Attempt to allocate %ld bytes",size); size=1; } #if DT_OS == 'd' && DT_CC == 'b' ret = farmalloc( size); #else if ((size_t) size != size) ProgError ("MM03", "Tried to allocate %ld b but couldn't; use another compiler", size); ret = malloc((size_t) size); #endif if (ret==NULL) ProgError("MM04", "Out of memory (needed %ld bytes)", size); return ret; }
/*return FALSE if read End*/ Bool TXTreadTexDef(struct TXTFILE *TXT,char name[8],Int16 *szx,Int16 *szy) { if(TXTok!=TRUE) Bug("TR71", "TxtTxd"); if(TXTskipComment(TXT)==FALSE) return FALSE; /*End*/ if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR73", "%s(%ld): expecting identifier", fname (TXT->pathname), (long) TXT->Lines); Normalise(name,name); *szx=TXTreadShort(TXT); *szy=TXTreadShort(TXT); return TRUE; }
/* copy bytes from a binary file to another with error checking */ void CopyBytes( FILE *dest, FILE *source, long size) { void huge *data; if (GameVersion % 16 == 0) /* check for shareware */ return; data = GetFarMemory( 0x8000 + 2); while (size > 0x8000) { if (fread( data, 1, 0x8000, source) != 0x8000) ProgError( "error reading from file"); if (fwrite( data, 1, 0x8000, dest) != 0x8000) ProgError( "error writing to file"); size -= 0x8000; } if (fread( data, 1, size, source) != size) ProgError( "error reading from file"); if (fwrite( data, 1, size, dest) != size) ProgError( "error writing to file"); FreeFarMemory( data); }
void check_types (void) { const type_check_t *t; for (t = type_checks; t - type_checks < sizeof type_checks / sizeof *t; t++) { /* FIXME Perhaps too strict. Wouldn't "<" suffice ? */ if (t->actual_size != t->mandated_size) ProgError ("Type %s has size %d (should be %d)." " Fix deutex.h and recompile.", t->name, (int) t->actual_size, (int) t->mandated_size); } }
/*read a patch def. Return FALSE if could not find '*' */ Bool TXTreadPatchDef(struct TXTFILE *TXT,char name[8],Int16 *ofsx,Int16 *ofsy) { if(TXTok!=TRUE) Bug("TR81", "TxtRpd"); if(TXTskipComment(TXT)==FALSE) return FALSE; if(TXTcheckStartPatch(TXT)!=TRUE) return FALSE; /*not a patch line*/ if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR83", "%s(%ld): expecting identifier", fname (TXT->pathname), (long) TXT->Lines); Normalise(name,name); *ofsx=TXTreadShort(TXT); *ofsy=TXTreadShort(TXT); return TRUE; }
/* ** 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); }
static Bool TXTreadIdent(struct TXTFILE *TXT,char name[8]) { if(TXTok!=TRUE) Bug("TR21", "%s: TxtRid", fname (TXT->pathname)); if(TXTskipComment(TXT)==FALSE) return FALSE; /*check end of section*/ if((TXT->Lines)>(TXT->SectionEnd)) { if(TXTboundSection(TXT)==FALSE) return FALSE; /*no other section*/ } if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) ProgError("TR23", "%s(%ld): expected identifier or \"END:\"", TXT->pathname, (long) TXT->Lines); Normalise(name,name); return TRUE; }
/*return false if read End*/ bool TXTreadTexDef(struct TXTFILE * TXT, char name[8], int16_t * szx, int16_t * szy) { if (!TXTok) Bug("TR71", "TxtTxd"); if (!TXTskipComment(TXT)) return false; /*End */ if (!TXTread(TXT, name, NAME | NUMBER)) ProgError("TR73", "%s(%ld): expecting identifier", fname(TXT->pathname), (long) TXT->Lines); Normalise(name, name); *szx = TXTreadShort(TXT); *szy = TXTreadShort(TXT); return true; }
bool TXTentryParse(char *name, char *filenam, int16_t * x, int16_t * y, bool * repeat, struct TXTFILE * TXT, bool XY) { int16_t c = 0, val = 0; bool comment; int16_t xx = INVALIDINT, yy = INVALIDINT; if (!TXTreadIdent(TXT, name)) return false; /* skip the equal */ if (!TXTgetc(TXT, &c, &val)) return false; if (c != '=') TXTungetc(TXT); /* read integer */ if (XY) { xx = TXTreadOptionalShort(TXT); yy = TXTreadOptionalShort(TXT); } Normalise(filenam, name); TXTreadOptionalName(TXT, filenam); if (XY) { if (xx == INVALIDINT) xx = TXTreadOptionalShort(TXT); if (yy == INVALIDINT) yy = TXTreadOptionalShort(TXT); } *repeat = TXTreadOptionalRepeat(TXT); *x = xx; *y = yy; for (comment = false;;) { if (!TXTgetc(TXT, &c, &val)) break; if (val & NEWLINE) break; if (val & COMMENT) { /*eat commentaries */ comment = true; continue; } if (val & SPACE) { /*eat space */ continue; } if (!comment) ProgError("TR87", "%s(%ld): bad entry format", fname(TXT->pathname), (long) TXT->Lines); } return true; }
char *ConvertFilePath(char *filename) { char *cp; if (filename == NULL) ProgError("BUG: cannot convert a NULL pathname"); for (cp = filename; *cp; cp++) if (*cp == '/' || *cp == '\\') { #ifdef QEU_DOS *cp = '\\'; #else *cp = '/'; #endif } return filename; }
/*read a patch def. Return false if could not find '*' */ bool TXTreadPatchDef(struct TXTFILE * TXT, char name[8], int16_t * ofsx, int16_t * ofsy) { if (!TXTok) Bug("TR81", "TxtRpd"); if (!TXTskipComment(TXT)) return false; if (!TXTcheckStartPatch(TXT)) return false; /*not a patch line */ if (!TXTread(TXT, name, NAME | NUMBER)) ProgError("TR83", "%s(%ld): expecting identifier", fname(TXT->pathname), (long) TXT->Lines); Normalise(name, name); *ofsx = TXTreadShort(TXT); *ofsy = TXTreadShort(TXT); return true; }
/* ** STEQUAL is used to indicate alternate name */ static void TXTreadOptionalName(struct TXTFILE *TXT,char name[8]) { Int16 c=0,val=0; while(1) { if(TXTgetc(TXT,&c,&val)!=TRUE) return; if(!(val & NEWLINE)) { if(val & STEQUAL) continue; /*skip '='*/ if(val & SPACE) continue; /*skip space*/ if(val & (NAME&(~NUMBER))) break; } TXTungetc(TXT); return; /*name is NOT modified*/ } TXTungetc(TXT); if(TXTread(TXT,name,NAME|NUMBER)!=TRUE) { ProgError("TR32", "%s(%ld): invalid optional name", TXT->pathname, (long) TXT->Lines); } }
/* ** Take some entries from a WAD */ static void HDRplunderWad(struct WADINFO *rwad,struct WADINFO *ewad) { char *data; Int32 wsize,sz=0; Int32 ostart,osize; Int16 n; Int32 oldfilesz; /* ** calculate required size */ oldfilesz=WADRposition(rwad); /*old file size*/ /* ** copy entries from WAD */ Phase("ME10", "Copying entries from wad (please wait)"); data = (char *)Malloc(MEMORYCACHE); for(n=0;n<(rwad->ntry);n++) { /*if((n&0x7F)==0) Phase("."); FIXME need /dev/tty output */ ostart=rwad->dir[n].start; osize=rwad->dir[n].size; /*detect external entries */ if(ostart&EXTERNAL) { /*update new directory*/ WADRalign4(rwad); rwad->dir[n].start=WADRposition(rwad); /*get entry size*/ if(osize>0) { /*copy old entry */ WADRseek(ewad,ostart&(~EXTERNAL)); for(wsize=0;wsize<osize;wsize+=sz) { sz=(osize-wsize>MEMORYCACHE)? MEMORYCACHE:osize-wsize; WADRreadBytes(ewad,data,sz); if(WADRwriteBytes2(rwad,data,sz)<0) { WADRchsize(rwad,oldfilesz); ProgError("ME13", "Not enough disk space"); break; } } } } } /*Phase("\n"); FIXME need /dev/tty output */ Free(data); }
void PSTmergeWAD(const char *doomwad,const char *wadin,NTRYB select) { static struct WADINFO iwad; static struct WADINFO pwad; ENTRY *iiden; /*identify entry in IWAD*/ ENTRY *piden; /*identify entry in PWAD*/ Int16 pnm;char *Pnam;Int32 Pnamsz=0; Int32 dirpos,ntry,isize,pstart,psize,time; struct WADDIR *NewDir;Int32 NewNtry; Phase("ME46", "Attempting to merge iwad %s and pwad %s", fname (doomwad), wadin); /*open iwad,get iwad directory*/ iwad.ok=0; WADRopenR(&iwad,doomwad); /*find PNAMES*/ pnm=WADRfindEntry(&iwad,"PNAMES"); if(pnm<0) ProgError("ME49", "Can't find PNAMES in iwad"); Pnam=WADRreadEntry(&iwad,pnm,&Pnamsz); /* identify iwad*/ iiden=IDENTentriesIWAD(&iwad, Pnam, Pnamsz,TRUE); /* get pwad directory, and identify*/ pwad.ok=0; WADRopenR(&pwad,wadin); piden=IDENTentriesPWAD(&pwad, Pnam, Pnamsz); /**/ Free(Pnam); /*where to put pwad? at pwadstart*/ /* merge the two directories */ NewDir=LISmergeDir(&NewNtry,FALSE,TRUE,select,&iwad,iiden,0,&pwad,piden, EXTERNAL); /* prepare for append*/ time=WADRprepareAppend(doomwad,&iwad,NewDir,NewNtry,&dirpos,&ntry,&isize); /* complete IWAD with PWAD, restorable*/ pstart=HDRinsertWad(&iwad,&pwad,&psize); /* set directory */ HDRsetDir(&iwad,TRUE,TRUE,time,dirpos,ntry,isize,pstart,psize,wadin); /* close */ WADRclose(&pwad); WADRclose(&iwad); }