DEADSOFTWARE

4c3e9aeee201630ac4394980ba2d6f2d86f7cd6c
[d2df-sdl.git] / src / shared / WADEDITOR.pas
1 unit WADEDITOR;
3 {$DEFINE SFS_DWFAD_DEBUG}
5 interface
7 uses
8 sfs, xstreams;
11 type
12 SArray = array of ShortString;
14 TWADEditor_1 = class(TObject)
15 private
16 fFileName: string; // empty: not opened
17 fIter: TSFSFileList;
19 function getIsOpen (): Boolean;
21 public
22 constructor Create();
23 destructor Destroy(); override;
25 procedure FreeWAD();
27 function ReadFile (FileName: string): Boolean;
28 function ReadMemory (Data: Pointer; Len: LongWord): Boolean;
29 function GetResource (Section, Resource: string; var pData: Pointer; var Len: Integer): Boolean;
30 function GetResourcesList (Section: string): SArray;
32 property isOpen: Boolean read getIsOpen;
33 end;
35 {
36 const
37 DFWAD_NOERROR = 0;
38 DFWAD_ERROR_WADNOTFOUND = -1;
39 DFWAD_ERROR_CANTOPENWAD = -2;
40 DFWAD_ERROR_RESOURCENOTFOUND = -3;
41 DFWAD_ERROR_FILENOTWAD = -4;
42 DFWAD_ERROR_WADNOTLOADED = -5;
43 DFWAD_ERROR_READRESOURCE = -6;
44 DFWAD_ERROR_READWAD = -7;
45 DFWAD_ERROR_WRONGVERSION = -8;
46 }
49 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String); overload;
50 procedure g_ProcessResourceStr (ResourceStr: String; FileName, SectionName, ResourceName: PString); overload;
53 implementation
55 uses
56 SysUtils, Classes, BinEditor, e_log, g_options;
59 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String);
60 var
61 a, i: Integer;
63 begin
64 //e_WriteLog(Format('g_ProcessResourceStr0: [%s]', [ResourceStr]), MSG_NOTIFY);
65 for i := Length(ResourceStr) downto 1 do
66 if ResourceStr[i] = ':' then
67 Break;
69 FileName := Copy(ResourceStr, 1, i-1);
71 for a := i+1 to Length(ResourceStr) do
72 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
74 ResourceName := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
75 SectionName := Copy(ResourceStr, i+1, Length(ResourceStr)-Length(ResourceName)-Length(FileName)-2);
76 end;
79 procedure g_ProcessResourceStr (ResourceStr: AnsiString; FileName, SectionName, ResourceName: PAnsiString);
80 var
81 a, i, l1, l2: Integer;
83 begin
84 //e_WriteLog(Format('g_ProcessResourceStr1: [%s]', [ResourceStr]), MSG_NOTIFY);
85 for i := Length(ResourceStr) downto 1 do
86 if ResourceStr[i] = ':' then
87 Break;
89 if FileName <> nil then
90 begin
91 FileName^ := Copy(ResourceStr, 1, i-1);
92 l1 := Length(FileName^);
93 end
94 else
95 l1 := 0;
97 for a := i+1 to Length(ResourceStr) do
98 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
100 if ResourceName <> nil then
101 begin
102 ResourceName^ := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
103 l2 := Length(ResourceName^);
104 end
105 else
106 l2 := 0;
108 if SectionName <> nil then
109 SectionName^ := Copy(ResourceStr, i+1, Length(ResourceStr)-l2-l1-2);
110 end;
113 { TWADEditor_1 }
114 constructor TWADEditor_1.Create();
115 begin
116 fFileName := '';
117 end;
120 destructor TWADEditor_1.Destroy();
121 begin
122 FreeWAD();
123 inherited;
124 end;
127 function TWADEditor_1.getIsOpen (): Boolean;
128 begin
129 result := (fFileName <> '');
130 end;
133 procedure TWADEditor_1.FreeWAD();
134 begin
135 if fIter <> nil then FreeAndNil(fIter);
136 //if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
137 fFileName := '';
138 end;
141 function TWADEditor_1.GetResource (Section, Resource: string; var pData: Pointer; var Len: Integer): Boolean;
142 var
143 f: Integer;
144 fi: TSFSFileInfo;
145 fs: TStream;
146 //fn: string;
147 begin
148 Result := False;
149 if not isOpen or (fIter = nil) then Exit;
150 if length(Resource) = 0 then Exit; // just in case
151 if (length(Section) <> 0) and (Section[length(Section)] <> '/') then Section := Section+'/';
152 for f := 0 to fIter.Count-1 do
153 begin
154 fi := fIter.Files[f];
155 if fi = nil then continue;
156 //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s] (%d, %d)', [Section, Resource, fFileName, fi.path, fi.name, SFSStrEqu(fi.path, Section), SFSStrEqu(fi.name, Resource)]), MSG_NOTIFY);
157 if {SFSStrEqu}SFSDFPathEqu(fi.path, Section) and SFSStrEqu(fi.name, Resource) then
158 begin
159 // i found her!
160 //fn := fFileName+'::'+fi.path+fi.name;
161 //fs := SFSFileOpen(fn);
162 try
163 fs := fIter.volume.OpenFileByIndex(f);
164 except
165 fs := nil;
166 end;
167 if fs = nil then
168 begin
169 e_WriteLog(Format('DFWAD: can''t open file [%s%s] in [%s]', [Section, Resource, fFileName]), MSG_WARNING);
170 break;
171 end;
172 Len := Integer(fs.size);
173 GetMem(pData, Len);
174 fs.ReadBuffer(pData^, Len);
175 fs.Free;
176 result := true;
177 {$IFDEF SFS_DWFAD_DEBUG}
178 if gSFSDebug then
179 e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY);
180 {$ENDIF}
181 exit;
182 end;
183 end;
184 e_WriteLog(Format('DFWAD: file [%s%s] not found in [%s]', [Section, Resource, fFileName]), MSG_WARNING);
185 end;
188 function TWADEditor_1.GetResourcesList (Section: string): SArray;
189 var
190 f: Integer;
191 fi: TSFSFileInfo;
192 begin
193 Result := nil;
194 if not isOpen or (fIter = nil) then Exit;
195 if (length(Section) <> 0) and (Section[length(Section)] <> '/') then Section := Section+'/';
196 for f := 0 to fIter.Count-1 do
197 begin
198 fi := fIter.Files[f];
199 if fi = nil then continue;
200 if length(fi.name) = 0 then continue;
201 if {SFSStrEqu}SFSDFPathEqu(fi.path, Section) then
202 begin
203 SetLength(result, Length(result)+1);
204 result[high(result)] := fi.name;
205 end;
206 end;
207 end;
210 function TWADEditor_1.ReadFile (FileName: string): Boolean;
211 var
212 rfn: string;
213 //f: Integer;
214 //fi: TSFSFileInfo;
215 begin
216 Result := False;
217 //e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
218 FreeWAD();
219 rfn := FileName;
220 if not FileExists(rfn) then
221 begin
222 //if length(rfn) >= 4 then e_WriteLog(Format('XXXX TWADEditor_1.ReadFile: [%s] [%s]', [Copy(rfn, length(rfn)-3, 4), Copy(rfn, 1, length(rfn)-4)]), MSG_NOTIFY);
223 if (length(rfn) >= 4) and SFSStrEqu(Copy(rfn, length(rfn)-3, 4), '.wad') then
224 begin
225 rfn := Copy(rfn, 1, length(rfn)-4);
226 if FileExists(rfn+'.pk3') then rfn := rfn+'.pk3'
227 else if FileExists(rfn+'.zip') then rfn := rfn+'.zip'
228 else rfn := FileName;
229 {.$IFDEF SFS_DWFAD_DEBUG}
230 if gSFSDebug then
231 if FileExists(rfn) then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
232 {.$ENDIF}
233 end;
234 end;
235 if not FileExists(rfn) then exit;
236 {$IFDEF SFS_DWFAD_DEBUG}
237 if gSFSDebug then
238 e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
239 {$ENDIF}
240 // cache this wad
241 SFSAddDataFile(rfn);
242 fIter := SFSFileList(rfn);
243 if fIter = nil then Exit;
244 fFileName := rfn;
245 {$IFDEF SFS_DWFAD_DEBUG}
246 if gSFSDebug then
247 e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
248 {$ENDIF}
250 for f := 0 to fIter.Count-1 do
251 begin
252 fi := fIter.Files[f];
253 if fi = nil then continue;
254 e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, fi.size]), MSG_NOTIFY);
255 end;
257 Result := True;
258 end;
261 var
262 uniqueCounter: Integer = 0;
264 function TWADEditor_1.ReadMemory (Data: Pointer; Len: LongWord): Boolean;
265 var
266 fn: string;
267 st: TStream = nil;
268 //f: Integer;
269 //fi: TSFSFileInfo;
270 begin
271 Result := False;
272 FreeWAD();
273 if (Data = nil) or (Len = 0) then
274 begin
275 e_WriteLog('TWADEditor_1.ReadMemory: EMPTY SUBWAD!', MSG_WARNING);
276 Exit;
277 end;
279 fn := Format(' -- memwad %d -- ', [uniqueCounter]);
280 Inc(uniqueCounter);
281 {$IFDEF SFS_DWFAD_DEBUG}
282 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
283 {$ENDIF}
285 try
286 st := TSFSMemoryStreamRO.Create(Data, Len);
287 if not SFSAddSubDataFile(fn, st) then
288 begin
289 st.Free;
290 Exit;
291 end;
292 except
293 st.Free;
294 Exit;
295 end;
297 fIter := SFSFileList(fn);
298 if fIter = nil then Exit;
300 fFileName := fn;
301 {$IFDEF SFS_DWFAD_DEBUG}
302 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
303 {$ENDIF}
306 for f := 0 to fIter.Count-1 do
307 begin
308 fi := fIter.Files[f];
309 if fi = nil then continue;
310 st := fIter.volume.OpenFileByIndex(f);
311 if st = nil then
312 begin
313 e_WriteLog(Format('[%s]: [%s : %s] CAN''T OPEN', [fFileName, fi.path, fi.name]), MSG_NOTIFY);
314 end
315 else
316 begin
317 e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, st.size]), MSG_NOTIFY);
318 st.Free;
319 end;
320 end;
321 //fIter.volume.OpenFileByIndex(0);
324 Result := True;
325 end;
328 begin
329 sfsDiskDirs := '<exedir>/data'; //FIXME
330 end.