3 {$DEFINE SFS_DWFAD_DEBUG}
12 SArray
= array of ShortString;
14 TWADEditor_1
= class(TObject
)
16 fFileName
: string; // empty: not opened
19 function getIsOpen (): Boolean;
23 destructor Destroy(); override;
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
;
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;
49 procedure g_ProcessResourceStr (ResourceStr
: String; var FileName
, SectionName
, ResourceName
: String); overload
;
50 procedure g_ProcessResourceStr (ResourceStr
: String; FileName
, SectionName
, ResourceName
: PString); overload
;
56 SysUtils
, Classes
, BinEditor
, e_log
, g_options
;
59 procedure g_ProcessResourceStr (ResourceStr
: String; var FileName
, SectionName
, ResourceName
: String);
64 //e_WriteLog(Format('g_ProcessResourceStr0: [%s]', [ResourceStr]), MSG_NOTIFY);
65 for i
:= Length(ResourceStr
) downto 1 do
66 if ResourceStr
[i
] = ':' then
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);
79 procedure g_ProcessResourceStr (ResourceStr
: AnsiString; FileName
, SectionName
, ResourceName
: PAnsiString);
81 a
, i
, l1
, l2
: Integer;
84 //e_WriteLog(Format('g_ProcessResourceStr1: [%s]', [ResourceStr]), MSG_NOTIFY);
85 for i
:= Length(ResourceStr
) downto 1 do
86 if ResourceStr
[i
] = ':' then
89 if FileName
<> nil then
91 FileName
^ := Copy(ResourceStr
, 1, i
-1);
92 l1
:= Length(FileName
^);
97 for a
:= i
+1 to Length(ResourceStr
) do
98 if (ResourceStr
[a
] = '\') or (ResourceStr
[a
] = '/') then Break
;
100 if ResourceName
<> nil then
102 ResourceName
^ := Copy(ResourceStr
, a
+1, Length(ResourceStr
)-Abs(a
));
103 l2
:= Length(ResourceName
^);
108 if SectionName
<> nil then
109 SectionName
^ := Copy(ResourceStr
, i
+1, Length(ResourceStr
)-l2
-l1
-2);
114 constructor TWADEditor_1
.Create();
120 destructor TWADEditor_1
.Destroy();
127 function TWADEditor_1
.getIsOpen (): Boolean;
129 result
:= (fFileName
<> '');
133 procedure TWADEditor_1
.FreeWAD();
135 if fIter
<> nil then FreeAndNil(fIter
);
136 //if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
141 function removeExt (s
: string): string;
146 while (i
> 1) and (s
[i
-1] <> '.') and (s
[i
-1] <> '/') do Dec(i
);
147 if (i
> 1) and (s
[i
-1] = '.') then
149 //writeln('[', s, '] -> [', Copy(s, 1, i-2), ']');
150 s
:= Copy(s
, 1, i
-2);
155 function TWADEditor_1
.GetResource (Section
, Resource
: string; var pData
: Pointer; var Len
: Integer): Boolean;
164 if not isOpen
or (fIter
= nil) then Exit
;
165 if length(Resource
) = 0 then Exit
; // just in case
166 if (length(Section
) <> 0) and (Section
[length(Section
)] <> '/') then Section
:= Section
+'/';
167 // backwards, due to possible similar names and such
168 for f
:= fIter
.Count
-1 downto 0 do
170 fi
:= fIter
.Files
[f
];
171 if fi
= nil then continue
;
172 //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s]', [Section, Resource, fFileName, fi.path, fi.name]), MSG_NOTIFY);
173 if {SFSStrEqu}SFSDFPathEqu(fi
.path
, Section
) and SFSStrEqu(removeExt(fi
.name
), Resource
) then
176 //fn := fFileName+'::'+fi.path+fi.name;
177 //fs := SFSFileOpen(fn);
179 fs
:= fIter
.volume
.OpenFileByIndex(f
);
185 e_WriteLog(Format('DFWAD: can''t open file [%s%s] in [%s]', [Section
, Resource
, fFileName
]), MSG_WARNING
);
188 Len
:= Integer(fs
.size
);
192 fs
.ReadBuffer(pData
^, Len
);
204 {$IFDEF SFS_DWFAD_DEBUG}
206 e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section
, Resource
, fFileName
, Len
]), MSG_NOTIFY
);
211 e_WriteLog(Format('DFWAD: file [%s%s] not found in [%s]', [Section
, Resource
, fFileName
]), MSG_WARNING
);
215 function TWADEditor_1
.GetResourcesList (Section
: string): SArray
;
221 if not isOpen
or (fIter
= nil) then Exit
;
222 if (length(Section
) <> 0) and (Section
[length(Section
)] <> '/') then Section
:= Section
+'/';
223 for f
:= 0 to fIter
.Count
-1 do
225 fi
:= fIter
.Files
[f
];
226 if fi
= nil then continue
;
227 if length(fi
.name
) = 0 then continue
;
228 if {SFSStrEqu}SFSDFPathEqu(fi
.path
, Section
) then
230 SetLength(result
, Length(result
)+1);
231 result
[high(result
)] := removeExt(fi
.name
);
237 function TWADEditor_1
.ReadFile (FileName
: string): Boolean;
244 //e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
246 path
:= ExtractFilePath(FileName
);
247 rfn
:= ExtractFileName(FileName
);
248 if not sfsFindFileCI(path
, rfn
) then
250 //{if gSFSDebug then} e_WriteLog(Format('TWADEditor_1.ReadFile: error looking for [%s] [%s]', [path, ExtractFileName(FileName)]), MSG_NOTIFY);
251 if SFSStrEqu(ExtractFileExt(FileName
), '.wad') then
253 rfn
:= ChangeFileExt(ExtractFileName(FileName
), '.pk3');
254 //{if gSFSDebug then} e_WriteLog(Format(' looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
255 if not sfsFindFileCI(path
, rfn
) then
257 //{if gSFSDebug then} e_WriteLog(Format(' looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
258 rfn
:= ChangeFileExt(ExtractFileName(FileName
), '.zip');
259 if not sfsFindFileCI(path
, rfn
) then exit
;
266 //{if gSFSDebug then} e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
270 //if rfn <> ExtractFileName(FileName) then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
272 {$IFDEF SFS_DWFAD_DEBUG}
273 if gSFSDebug
then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn
]), MSG_NOTIFY
);
280 if not SFSAddDataFile(rfn
, true) then exit
;
284 if not SFSAddDataFileTemp(rfn
, true) then exit
;
289 fIter
:= SFSFileList(rfn
);
290 if fIter
= nil then Exit
;
292 {$IFDEF SFS_DWFAD_DEBUG}
294 e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName
]), MSG_NOTIFY
);
297 for f := 0 to fIter.Count-1 do
299 fi := fIter.Files[f];
300 if fi = nil then continue;
301 e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, fi.size]), MSG_NOTIFY);
309 uniqueCounter
: Integer = 0;
311 function TWADEditor_1
.ReadMemory (Data
: Pointer; Len
: LongWord): Boolean;
320 if (Data
= nil) or (Len
= 0) then
322 e_WriteLog('TWADEditor_1.ReadMemory: EMPTY SUBWAD!', MSG_WARNING
);
326 fn
:= Format(' -- memwad %d -- ', [uniqueCounter
]);
328 {$IFDEF SFS_DWFAD_DEBUG}
329 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn
]), MSG_NOTIFY
);
333 st
:= TSFSMemoryStreamRO
.Create(Data
, Len
);
334 if not SFSAddSubDataFile(fn
, st
, true) then
344 fIter
:= SFSFileList(fn
);
345 if fIter
= nil then Exit
;
348 {$IFDEF SFS_DWFAD_DEBUG}
349 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName
]), MSG_NOTIFY
);
353 for f := 0 to fIter.Count-1 do
355 fi := fIter.Files[f];
356 if fi = nil then continue;
357 st := fIter.volume.OpenFileByIndex(f);
360 e_WriteLog(Format('[%s]: [%s : %s] CAN''T OPEN', [fFileName, fi.path, fi.name]), MSG_NOTIFY);
364 e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, st.size]), MSG_NOTIFY);
368 //fIter.volume.OpenFileByIndex(0);
376 sfsDiskDirs
:= '<exedir>/data'; //FIXME