1 {$INCLUDE ../shared/a_modes.inc}
3 {$IFDEF WINDOWS}
4 {$APPTYPE CONSOLE}
5 {$ENDIF}
7 uses
8 SysUtils, Classes,
9 {$IFDEF USE_SDL}
10 SDL in '../lib/sdl/sdl.pas',
11 {$ENDIF}
12 {$IFDEF USE_SDL2}
13 SDL2 in '../lib/sdl2/sdl2.pas',
14 {$ENDIF}
15 sfs in '../sfs/sfs.pas',
16 sfsPlainFS in '../sfs/sfsPlainFS.pas',
17 sfsZipFS in '../sfs/sfsZipFS.pas',
18 mempool in '../shared/mempool.pas',
19 xstreams in '../shared/xstreams.pas',
20 xparser in '../shared/xparser.pas',
21 xdynrec in '../shared/xdynrec.pas',
22 xprofiler in '../shared/xprofiler.pas',
23 utils in '../shared/utils.pas',
24 hashtable in '../shared/hashtable.pas',
25 conbuf in '../shared/conbuf.pas',
26 e_log in '../engine/e_log.pas',
27 wadreader in '../shared/wadreader.pas',
28 MAPDEF in '../shared/MAPDEF.pas';
31 // ////////////////////////////////////////////////////////////////////////// //
32 var
33 pr: TTextParser;
34 dfmapdef: TDynMapDef;
35 wr: TTextWriter;
36 map: TDynRecord;
37 st: TStream;
38 stt: UInt64;
39 inname: AnsiString = '';
40 outname: AnsiString = '';
41 totext: Integer = -1; // <0: guess; force outname extension
42 //sign: packed array[0..3] of AnsiChar;
43 wad: TWADFile = nil;
44 waddata: Pointer;
45 waddlen: Integer;
46 wasbin: Boolean = false;
47 lostdata: Boolean;
48 begin
49 if (ParamCount = 0) then
50 begin
51 writeln('usage: mapcvt inname outname');
52 Halt(1);
53 end;
55 inname := ParamStr(1);
56 //writeln('inname: [', inname, ']');
57 if (ParamCount = 1) then
58 begin
59 outname := forceFilenameExt(ParamStr(1), '');
60 if isWadPath(outname) then
61 begin
62 outname := SFSReplacePathDelims(g_ExtractFilePathName(outname), '/');
63 if (Length(outname) = 0) then begin writeln('FATAL: can''t guess output name!'); Halt(1); end;
64 end;
65 end
66 else
67 begin
68 outname := ParamStr(2);
69 if StrEquCI1251(getFilenameExt(outname), '.txt') then totext := 1
70 else if StrEquCI1251(getFilenameExt(outname), '.map') then totext := 0
71 else if StrEquCI1251(getFilenameExt(outname), '.dfmap') then totext := 0
72 else if (Length(getFilenameExt(outname)) = 0) then totext := -1
73 else begin writeln('FATAL: can''t guess output format!'); Halt(1); end;
74 end;
75 //writeln('outname: [', outname, ']; totext=', totext);
77 e_InitWritelnDriver();
78 conbufDumpToStdOut := true;
79 conbufConPrefix := false;
81 writeln('parsing "mapdef.txt"...');
82 //pr := TFileTextParser.Create('mapdef.txt');
83 pr := TStrTextParser.Create(defaultMapDef);
84 try
85 dfmapdef := TDynMapDef.Create(pr);
86 except on e: Exception do
87 begin
88 writeln('ERROR at (', pr.line, ',', pr.col, '): ', e.message);
89 Halt(1);
90 end;
91 end;
93 writeln('parsing "', inname, '"...');
95 if isWadPath(inname) then
96 begin
97 wad := TWADFile.Create();
98 wad.ReadFile(g_ExtractWadName(inname));
99 wad.GetMapResource(g_ExtractFilePathName(inname), waddata, waddlen);
100 st := TSFSMemoryChunkStream.Create(waddata, waddlen, true);
101 wad.Free();
102 end
103 else
104 begin
105 st := openDiskFileRO(inname);
106 end;
108 try
109 stt := getTimeMicro();
110 map := dfmapdef.parseMap(st, @wasbin);
111 stt := getTimeMicro()-stt;
112 if wasbin then write('binary') else write('text');
113 writeln(' map parsed in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
114 except
115 on e: TDynParseException do
116 begin
117 writeln('ERROR at (', e.tokLine, ',', e.tokCol, '): ', e.message);
118 Halt(1);
119 end;
120 on E: Exception do
121 begin
122 writeln('ERROR: ', e.message);
123 Halt(1);
124 end;
125 end;
127 {$IF DEFINED(D2D_DYNREC_PROFILER)}xdynDumpProfiles();{$ENDIF}
129 if (totext < 0) then
130 begin
131 if wasbin then begin outname := forceFilenameExt(outname, '.txt'); totext := 1; end
132 else begin outname := forceFilenameExt(outname, '.map'); totext := 0; end;
133 end;
135 assert(totext >= 0);
137 writeln('writing "', outname, '"...');
138 st := createDiskFile(outname);
139 if (totext = 0) then
140 begin
141 // write binary map
142 lostdata := false;
143 stt := getTimeMicro();
144 map.writeBinTo(lostdata, st);
145 stt := getTimeMicro()-stt;
146 if lostdata then writeln('***WARNING! some data was lost due to binary format limitations!');
147 write('binary');
148 end
149 else
150 begin
151 // write text map
152 wr := TFileTextWriter.Create(st);
153 stt := getTimeMicro();
154 map.writeTo(wr);
155 stt := getTimeMicro()-stt;
156 wr.Free();
157 write('text');
158 end;
159 writeln(' map written in ', stt div 1000, '.', stt mod 1000, ' milliseconds');
160 end.