DEADSOFTWARE

textmap: dramatically increased text map parsing speed (text map now parses in the...
[d2df-sdl.git] / src / tools / mapcvt.dpr
1 {$INCLUDE ../shared/a_modes.inc}
2 {$IFDEF WINDOWS}
3 {$APPTYPE CONSOLE}
4 {$ENDIF}
6 uses
7 SysUtils, Classes,
8 sfs in '../sfs/sfs.pas',
9 sfsPlainFS in '../sfs/sfsPlainFS.pas',
10 sfsZipFS in '../sfs/sfsZipFS.pas',
11 xstreams in '../shared/xstreams.pas',
12 xparser in '../shared/xparser.pas',
13 xdynrec in '../shared/xdynrec.pas',
14 xprofiler in '../shared/xprofiler.pas',
15 utils in '../shared/utils.pas',
16 hashtable in '../shared/hashtable.pas',
17 conbuf in '../shared/conbuf.pas',
18 e_log in '../engine/e_log.pas',
19 wadreader in '../shared/wadreader.pas',
20 MAPDEF in '../shared/MAPDEF.pas';
23 // ////////////////////////////////////////////////////////////////////////// //
24 var
25 pr: TTextParser;
26 dfmapdef: TDynMapDef;
27 wr: TTextWriter;
28 map: TDynRecord;
29 st: TStream;
30 stt: UInt64;
31 inname: AnsiString = '';
32 outname: AnsiString = '';
33 totext: Integer = -1; // <0: guess; force outname extension
34 sign: packed array[0..3] of AnsiChar;
35 wad: TWADFile = nil;
36 waddata: Pointer;
37 waddlen: Integer;
38 begin
39 if (ParamCount = 0) then
40 begin
41 writeln('usage: mapcvt inname outname');
42 Halt(1);
43 end;
45 inname := ParamStr(1);
46 //writeln('inname: [', inname, ']');
47 if (ParamCount = 1) then
48 begin
49 outname := forceFilenameExt(ParamStr(1), '');
50 if isWadPath(outname) then
51 begin
52 outname := SFSReplacePathDelims(g_ExtractFilePathName(outname), '/');
53 if (Length(outname) = 0) then begin writeln('FATAL: can''t guess output name!'); Halt(1); end;
54 end;
55 end
56 else
57 begin
58 outname := ParamStr(2);
59 if StrEquCI1251(getFilenameExt(outname), '.txt') then totext := 1
60 else if StrEquCI1251(getFilenameExt(outname), '.map') then totext := 0
61 else if StrEquCI1251(getFilenameExt(outname), '.dfmap') then totext := 0
62 else if (Length(getFilenameExt(outname)) = 0) then totext := -1
63 else begin writeln('FATAL: can''t guess output format!'); Halt(1); end;
64 end;
65 //writeln('outname: [', outname, ']; totext=', totext);
67 e_InitWritelnDriver();
68 conbufDumpToStdOut := true;
69 conbufConPrefix := false;
71 writeln('parsing "mapdef.txt"...');
72 //pr := TFileTextParser.Create('mapdef.txt');
73 pr := TStrTextParser.Create(defaultMapDef);
74 try
75 dfmapdef := TDynMapDef.Create(pr);
76 except on e: Exception do
77 begin
78 writeln('ERROR at (', pr.line, ',', pr.col, '): ', e.message);
79 Halt(1);
80 end;
81 end;
83 writeln('parsing "', inname, '"...');
85 if isWadPath(inname) then
86 begin
87 wad := TWADFile.Create();
88 wad.ReadFile(g_ExtractWadName(inname));
89 wad.GetMapResource(g_ExtractFilePathName(inname), waddata, waddlen);
90 st := TSFSMemoryChunkStream.Create(waddata, waddlen, true);
91 wad.Free();
92 end
93 else
94 begin
95 st := openDiskFileRO(inname);
96 end;
98 st.ReadBuffer(sign, 4);
99 st.position := 0;
100 if (sign[0] = 'M') and (sign[1] = 'A') and (sign[2] = 'P') and (sign[3] = #1) then
101 begin
102 // binary map
103 if (totext < 0) then begin outname := forceFilenameExt(outname, '.txt'); totext := 1; end;
104 stt := curTimeMicro();
105 map := dfmapdef.parseBinMap(st);
106 stt := curTimeMicro()-stt;
107 writeln('binary map parsed in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
108 st.Free();
109 end
110 else
111 begin
112 // text map
113 if (totext < 0) then begin outname := forceFilenameExt(outname, '.map'); totext := 0; end;
114 pr := TFileTextParser.Create(st);
115 try
116 stt := curTimeMicro();
117 map := dfmapdef.parseMap(pr);
118 stt := curTimeMicro()-stt;
119 writeln('text map parsed in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
120 except on e: Exception do
121 begin
122 writeln('ERROR at (', pr.line, ',', pr.col, '): ', e.message);
123 Halt(1);
124 end;
125 end;
126 pr.Free();
127 end;
129 {$IF DEFINED(D2D_DYNREC_PROFILER)}xdynDumpProfiles();{$ENDIF}
131 assert(totext >= 0);
133 writeln('writing "', outname, '"...');
134 st := createDiskFile(outname);
135 if (totext = 0) then
136 begin
137 // write binary map
138 stt := curTimeMicro();
139 map.writeBinTo(st);
140 stt := curTimeMicro()-stt;
141 writeln('binary map written in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
142 end
143 else
144 begin
145 // write text map
146 wr := TFileTextWriter.Create(st);
147 stt := curTimeMicro();
148 map.writeTo(wr);
149 stt := curTimeMicro()-stt;
150 writeln('text map written in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
151 wr.Free();
152 end;
153 end.