7 Read whole file from wad
8 (data <> nil) and (len > 0) when ok
9 use FreeMem(data) when done
12 Read whole file from folded wad
13 (data <> nil) and (len > 0) when ok
14 use FreeMem(data) when done
21 Add/overwrite file to wad
25 Check that resource exists
29 procedure g_ReadResource (wad
, section
, name
: String; out data
: PByte; out len
: Integer);
30 procedure g_ReadSubResource (wad
, section0
, name0
, section1
, name1
: String; out data
: PByte; out len
: Integer);
31 procedure g_DeleteResource (wad
, section
, name
: String; out res
: Integer);
32 procedure g_AddResource (wad
, section
, name
: String; const data
: PByte; len
: Integer; out res
: Integer);
33 procedure g_ExistsResource (wad
, section
, name
: String; out res
: Integer);
37 uses sfs
, xstreams
, dfzip
, utils
, Classes
, SysUtils
, WADEDITOR
;
39 procedure g_AddResourceToDFWAD (wad
, section
, name
: String; const data
: PByte; len
: Integer; out res
: Integer);
44 section
:= utf2win(section
);
45 name
:= utf2win(name
);
46 f
:= TWADEditor_1
.Create();
47 if not f
.ReadFile(wad
) then
52 f
.RemoveResource(section
, name
);
53 f
.AddResource(data
, len
, name
, section
);
54 if FileExists(wad
) then
55 ASSERT(RenameFile(wad
, wad
+ '.bak'));
61 procedure g_AddResourceToZip (wad
, section
, name
: String; const data
: PByte; len
: Integer; out res
: Integer);
68 dir
: array of TFileInfo
;
70 procedure Add (name
: String; data
: PByte; len
: Integer);
71 var ds
: TSFSMemoryChunkStream
;
73 SetLength(dir
, n
+ 1);
74 ds
:= TSFSMemoryChunkStream
.Create(data
, len
, false);
75 dir
[n
] := dfzip
.ZipOne(ts
, name
, ds
);
82 wad
:= ExpandFileName(wad
);
83 section
:= utf2win(section
);
84 name
:= utf2win(name
);
85 list
:= SFSFileList(wad
);
86 tmp
:= wad
+ '.tmp' + IntToStr(Random(100000));
87 ts
:= TFileStream
.Create(tmp
, fmCreate
);
92 for i
:= 0 to list
.Count
- 1 do
94 if (list
.Files
[i
].path
<> section
) or (list
.Files
[i
].name
<> section
) then
96 g_ReadResource(wad
, list
.Files
[i
].path
, list
.Files
[i
].name
, data0
, len0
);
97 if list
.Files
[i
].path
= '' then
98 entry
:= list
.Files
[i
].name
100 entry
:= list
.Files
[i
].path
+ '/' + list
.Files
[i
].name
;
101 Add(entry
, data0
, len0
);
111 entry
:= section
+ '/' + name
;
113 Add(entry
, data
, len
);
114 dfzip
.writeCentralDir(ts
, dir
);
117 if FileExists(wad
) then
118 ASSERT(RenameFile(wad
, wad
+ '.bak'));
119 ASSERT(RenameFile(tmp
, wad
));
123 procedure g_AddResource (wad
, section
, name
: String; const data
: PByte; len
: Integer; out res
: Integer);
126 res
:= 2; (* unknown type *)
127 ext
:= LowerCase(SysUtils
.ExtractFileExt(wad
));
129 g_AddResourceToDFWAD(wad
, section
, name
, data
, len
, res
)
130 else if (ext
= '.pk3') or (ext
= '.zip') or (ext
= '.dfzip') then
131 g_AddResourceToZip(wad
, section
, name
, data
, len
, res
)
134 procedure g_DeleteResourceFromDFWAD (wad
, section
, name
: String; out res
: Integer);
137 res
:= 1; (* error *)
138 section
:= utf2win(section
);
139 name
:= utf2win(name
);
140 f
:= TWADEditor_1
.Create
;
141 if not f
.ReadFile(wad
) then
147 f
.RemoveResource(section
, name
);
153 procedure g_DeleteResourceFromZip (wad
, section
, name
: String; out res
: Integer);
160 dir
: array of TFileInfo
;
162 procedure Add (name
: String; data
: PByte; len
: Integer);
163 var ds
: TSFSMemoryChunkStream
;
165 SetLength(dir
, n
+ 1);
166 ds
:= TSFSMemoryChunkStream
.Create(data
, len
, false);
167 dir
[n
] := dfzip
.ZipOne(ts
, name
, ds
);
174 wad
:= ExpandFileName(wad
);
175 section
:= utf2win(section
);
176 name
:= utf2win(name
);
177 list
:= SFSFileList(wad
);
178 tmp
:= wad
+ '.tmp' + IntToStr(Random(100000));
179 ts
:= TFileStream
.Create(tmp
, fmCreate
);
184 for i
:= 0 to list
.Count
- 1 do
186 if (list
.Files
[i
].path
<> section
) or (list
.Files
[i
].name
<> section
) then
188 g_ReadResource(wad
, list
.Files
[i
].path
, list
.Files
[i
].name
, data0
, len0
);
189 if list
.Files
[i
].path
= '' then
190 entry
:= list
.Files
[i
].name
192 entry
:= list
.Files
[i
].path
+ '/' + list
.Files
[i
].name
;
193 Add(entry
, data0
, len0
);
200 dfzip
.writeCentralDir(ts
, dir
);
203 if FileExists(wad
) then
204 ASSERT(RenameFile(wad
, wad
+ '.bak'));
205 ASSERT(RenameFile(tmp
, wad
));
209 procedure g_DeleteResource (wad
, section
, name
: String; out res
: Integer);
212 res
:= 2; (* unknown type *)
213 ext
:= LowerCase(SysUtils
.ExtractFileExt(wad
));
215 g_DeleteResourceFromDFWAD(wad
, section
, name
, res
)
216 else if (ext
= '.pk3') or (ext
= '.zip') or (ext
= '.dfzip') then
217 g_DeleteResourceFromZip(wad
, section
, name
, res
)
220 procedure g_ExistsResource (wad
, section
, name
: String; out res
: Integer);
221 var str
: String; stream
: TStream
;
224 section
:= utf2win(section
);
225 name
:= utf2win(name
);
226 if SFSAddDataFileTemp(wad
, TRUE) then
228 str
:= SFSGetLastVirtualName(section
+ '\' + name
);
229 stream
:= SFSFileOpen(wad
+ '::' + str
);
230 if stream
<> nil then
239 procedure g_ReadResource (wad
, section
, name
: String; out data
: PByte; out len
: Integer);
240 var stream
: TStream
; str
: String; i
: Integer;
242 section
:= utf2win(section
);
243 name
:= utf2win(name
);
246 if SFSAddDataFileTemp(wad
, TRUE) then
248 str
:= SFSGetLastVirtualName(section
+ '\' + name
);
249 stream
:= SFSFileOpen(wad
+ '::' + str
);
250 if stream
<> nil then
255 //stream.ReadBuffer(data, len); (* leads to segfault *)
256 for i
:= 0 to len
- 1 do
257 data
[i
] := stream
.ReadByte();
264 procedure g_ReadSubResource (wad
, section0
, name0
, section1
, name1
: String; out data
: PByte; out len
: Integer);
265 var stream0
, stream1
: TStream
; str0
, str1
: String; i
: Integer;
269 if (wad
= '') OR (section0
= '') OR (name0
= '') OR (section1
= '') OR (name1
= '') then Exit
;
270 section0
:= utf2win(section0
);
271 name0
:= utf2win(name0
);
272 section1
:= utf2win(section1
);
273 name1
:= utf2win(name1
);
274 if SFSAddDataFileTemp(wad
, TRUE) then
276 str0
:= SFSGetLastVirtualName(section0
+ '\' + name0
);
277 stream0
:= SFSFileOpen(wad
+ '::' + str0
);
278 if stream0
<> nil then
280 if SFSAddSubDataFile(wad
+ '\' + str0
, stream0
, TRUE) then
282 str1
:= SFSGetLastVirtualName(section1
+ '\' + name1
);
283 stream1
:= SFSFileOpen(wad
+ '\' + str0
+ '::' + str1
);
284 if stream1
<> nil then
289 //stream1.ReadBuffer(data, len); (* leads to segfault *)
290 for i
:= 0 to len
- 1 do
291 data
[i
] := stream1
.ReadByte();