home *** CD-ROM | disk | FTP | other *** search
- program DirPWad;
-
- {
- 09/09/1994 v1.01 Added support for Doom ][
- Added support for multiple files and wildcards
- Layout changed
-
- }
-
- uses Dos;
-
-
- procedure help;
- begin
- writeln;
- writeln('DirPWad v1.01 (c)1994 R.Nijlunsing csg465@wing.rug.nl');
- writeln;
- writeln('Syntax:');
- writeln(' DIRPWAD <PWAD file(s)> [<PWAD file(s)> ..]');
- writeln('Wildcards are allowed');
- writeln;
- writeln('Example:');
- writeln(' I:\GREAT\GAMES\ID\DOOM1\1.666> dirpwad MyWad.wad');
- writeln('could produce:');
- writeln;
- writeln('MYWAD.WAD :');
- writeln(' E2M4 : 12 3');
- writeln(' E2M5 : 1234 0');
- writeln;
- writeln('which means:');
- writeln('''The file MyWad.WAD is a DOOM wad file which contains 2 levels:');
- writeln(' episode 2 mission 4 which can be played by 2 persons in coop mode');
- writeln(' and by a maximum of 3 persons in deathmatch. The other level,');
- writeln(' episode 2 mission 5, can be played in coop by 4 persons but');
- writeln(' not in deathmatch mode as there are no deathmatch-starts.''');
- writeln;
- halt(1);
- end;
-
- function Cstring(cs:string):string;
- { Converts <cs> (ASCIIZ) to a Pascal string }
- var
- s:string;
- i:integer;
- begin
- s:='';
- i:=0;
- while cs[i]<>#0 do begin
- s:=s+cs[i];
- inc(i);
- end;
- Cstring:=s;
- end;
-
- function exist(filename:string):boolean;
- { Returns TRUE if file <filename> exists, otherwise FALSE }
- var f:file of byte;
- begin
- assign(f,filename);
- {$I-}
- reset(f);
- {$I+}
- if IOResult<>0 then exist:=false
- else exist:=true;
- end;
-
- function Up(s:string):string;
- { Returns string <s> in uppercase }
- var p:integer; result:string;
- begin
- result:=s;
- for p:=1 to length(s) do
- result[p]:=upcase(result[p]);
- up:=result;
- end;
-
- procedure error(e:string; c:integer);
- begin
- writeln;
- writeln(' Fatal error: ',e);
- halt(c);
- end;
-
- procedure process_file(f:string);
- { Processes file with filename <f> }
- type
- Tsig = array[0..3] of char; { WAD signature {PWAD or IWAD) }
- Tthingentry = record { A 'thing' map entry : }
- x, y: integer; { Coordinates: (x,y) }
- angle: integer; { Orientation }
- typenr: integer; { Type (1=player 1 start etc.) }
- attr: word; { Attribute }
- end;
- Tresname = array[0..7] of char; { Type of resource name, ASCIIZ }
- Tdirentry = record { Type of directory entry (=resource) in WAD file }
- resstart: longint; { Offset begin resource }
- ressize: longint; { Size of resource in bytes }
- resname: Tresname; { Name of resource }
- end;
- const
- maxthingentries = 65000 div sizeof(Tthingentry);
- maxdirentries = 65000 div sizeof(Tdirentry);
- good_sig_PWAD: Tsig = 'PWAD'; { A good signature }
- good_sig_IWAD: Tsig = 'IWAD'; { The other possibility }
- type
- Tdir = array[0..maxdirentries-1] of Tdirentry; { Type of resource dir }
- Tthing = array[0..maxthingentries-1] of Tthingentry; { Type of things dir }
- var
- fn_input: string; { Filenames }
- fh_input: file; { Filehandles }
- header: record { Header of WAD file }
- sig: Tsig; { PWAD /IWAD signature }
- direntries: longint;{ # of entries in directory }
- dirstart: longint; { Offset begin directory }
- end;
- dirptr: ^Tdir; { Pointer to directory }
- dirsize: word; { Length of directory in bytes }
- thingptr: ^Tthing; { Pointer to thing directory }
- i,j:integer; { Index }
- playerstart:array[1..4] of boolean; { TRUE if playerstart[player] exists }
- dmstarts:integer; { # of deathmatch starts in a level }
- begin
- fn_input:=f;
- { Open file }
- assign(fh_input,fn_input);
- reset(fh_input,1);
- { Read WAD info }
- blockread(fh_input,header,sizeof(header));
- writeln(fn_input,' :');
- if (header.sig <> good_sig_PWAD) and
- (header.sig <> good_sig_IWAD) then begin
- close(fh_input);
- writeln(' Error: Invalid signature in file !');
- exit;
- end;
- if (header.direntries > maxdirentries) then begin
- writeln(' Warning: resource directory >64Kb; truncated');
- header.direntries:=maxdirentries;
- end;
- { Read directory }
- dirsize:=sizeof(Tdirentry)*header.direntries;
- if MaxAvail < dirsize then error('Out of memory',4);
- getmem(dirptr,dirsize);
- seek(fh_input,header.dirstart);
- blockread(fh_input,dirptr^,dirsize);
- { Scan for start new episode/mission }
- i:=0;
- while i<header.direntries do begin
- with dirptr^[i] do begin
- if ((resname[0]='E') and (resname[2]='M') and (resname[4]=#0)) or {ExMy}
- ((resname[0]='M') and (resname[1]='A') and (resname[2]='P') and {MAPxx}
- (resname[5]=#0)) then begin
- write(' ',Cstring(resname),' : ');
- end else
- if (resname='THINGS'#0#0) then begin
- { Now load the thing directory }
- seek(fh_input,resstart);
- if MaxAvail < ressize then begin
- writeln('Too many things; truncating');
- ressize:=(MaxAvail div 10)*10;
- end;
- getmem(thingptr,ressize);
- blockread(fh_input,thingptr^,ressize);
- dmstarts:=0;
- for j:=1 to 4 do
- playerstart[j]:=false;
- for j:=0 to (ressize div 10)-1 do
- case thingptr^[j].typenr of
- 1: playerstart[1]:=true; { Player 1 start .. }
- 2: playerstart[2]:=true; { Player 2 start .. }
- 3: playerstart[3]:=true; { Player 3 start .. }
- 4: playerstart[4]:=true; { Player 4 start .. }
- 11: inc(dmstarts); { Deathmatch start }
- end;
- for j:=1 to 4 do
- if playerstart[j] then write(j:1) else write(' ');
- write(' ');
- writeln(dmstarts:4);
- freemem(thingptr,ressize);
- end;
- end;
- inc(i); { Next resource }
- end;
- { Dispose directory }
- freemem(dirptr,dirsize);
- { Close file }
- close(fh_input);
- end;
-
-
- { Main program }
-
- var
- i:integer; { Parameters index }
- f:string;
- DirInfo:SearchRec;
- Dir:DirStr;
- Dummy1:NameStr;
- Dummy2:ExtStr;
- begin
- if (paramcount=0) then help;
- for i:=1 to paramcount do begin
- f:=up(paramstr(i));
- if exist(f+'.WAD') then
- process_file(f+'.WAD')
- else begin
- FindFirst(f,$2f, DirInfo); { Find all files }
- if (DosError<>0) then
- writeln('Warning: ''',f,''' not found')
- else begin
- Fsplit(f,Dir,dummy1,dummy2);
- while (DosError=0) do begin
- process_file(Dir+DirInfo.Name);
- FindNext(DirInfo);
- end;
- end;
- end;
- end;
- end.
-