X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Feditor%2Fg_resources.pas;h=85a78356f67bd3e6794c5394d075320b4a011f82;hb=dd6a8c0ae0c61fbd1d070e83b5d54c41edeb6df8;hp=9605b1a303361b5b85a3312ccfc02ab163845520;hpb=a140ef8433c5e5cdf3d2ec4a6343c5380535e200;p=d2df-editor.git diff --git a/src/editor/g_resources.pas b/src/editor/g_resources.pas index 9605b1a..85a7835 100644 --- a/src/editor/g_resources.pas +++ b/src/editor/g_resources.pas @@ -1,8 +1,17 @@ +{$ASSERTIONS ON} unit g_resources; interface (** + g_GetResourceSection + Parse path in form 'path/to/file.wad:some/section/resouce' to + wad = 'path/to/file.wad', section = 'some/section', name = 'resource' + + g_DeleteFile + Delete file if it exists. Make backup if enabled. + return true when file not exists. + g_ReadResource Read whole file from wad (data <> nil) and (len > 0) when ok @@ -26,7 +35,13 @@ interface res = 0 when ok **) + (* Editor options *) + var + Compress: Boolean; + Backup: Boolean; + procedure g_GetResourceSection (path: String; out wad, section, name: String); + function g_DeleteFile(wad: String; backupPostfix: String = '.bak'): Boolean; procedure g_ReadResource (wad, section, name: String; out data: PByte; out len: Integer); procedure g_ReadSubResource (wad, section0, name0, section1, name1: String; out data: PByte; out len: Integer); @@ -84,11 +99,31 @@ implementation wad := Copy(path, 1, i - 1); end; + function g_DeleteFile (wad: String; backupPostfix: String = '.bak'): Boolean; + var newwad: String; ok: Boolean; + begin + SFSGCCollect; + SFSGCCollect; + SFSGCCollect; + ok := true; + if FileExists(wad) then + begin + if Backup then + begin + newwad := wad + backupPostfix; + if FileExists(newwad) then ok := DeleteFile(newwad); + if ok then ok := RenameFile(wad, newwad); + end + else + ok := DeleteFile(wad); + end; + result := ok; + end; + procedure g_AddResourceToDFWAD (wad, section, name: String; const data: PByte; len: Integer; out res: Integer); var f: TWADEditor_1; begin res := 1; (* error *) - wad := utf2win(wad); section := utf2win(NoTrailing(section)); name := utf2win(name); ASSERT(name <> ''); @@ -100,12 +135,7 @@ implementation f.CreateImage; f.RemoveResource(section, name); f.AddResource(data, len, name, section); - if FileExists(wad) then - begin - if FileExists(wad + '.bak') then - ASSERT(DeleteFile(wad + '.bak')); - ASSERT(RenameFile(wad, wad + '.bak')) - end; + g_DeleteFile(wad); f.SaveTo(wad); f.Free; res := 0 @@ -119,13 +149,14 @@ implementation tmp, path: String; ts: TFileStream; dir: array of TFileInfo; + ok: Boolean; procedure Add (name: String; data: PByte; len: Integer); var ds: TSFSMemoryChunkStream; begin SetLength(dir, n + 1); - ds := TSFSMemoryChunkStream.Create(data, len, false); - dir[n] := dfzip.ZipOne(ts, name, ds); + ds := TSFSMemoryChunkStream.Create(data, len, False); + dir[n] := dfzip.ZipOne(ts, name, ds, Compress); ds.Free; INC(n); end; @@ -146,9 +177,9 @@ implementation for i := 0 to list.Count - 1 do begin path := NoTrailing(list.Files[i].path); - if (path <> section) or (list.Files[i].name <> section) then + if (path <> section) or (list.Files[i].name <> name) then begin - g_ReadResource(wad, path, list.Files[i].name, data0, len0); + g_ReadResource(wad, win2utf(path), win2utf(list.Files[i].name), data0, len0); ASSERT(data0 <> nil); if path = '' then path := list.Files[i].name @@ -170,14 +201,11 @@ implementation dfzip.writeCentralDir(ts, dir); ts.Free; - if FileExists(wad) then - begin - if FileExists(wad + '.bak') then - ASSERT(DeleteFile(wad + '.bak')); - ASSERT(RenameFile(wad, wad + '.bak')) - end; - ASSERT(RenameFile(tmp, wad)); - res := 0 + ok := g_DeleteFile(wad); + if not ok then e_WriteLog('Cant delete older wad [' + wad + ']', TRecordCategory.MSG_WARNING); + ok := RenameFile(tmp, wad); + if not ok then e_WriteLog('ERROR: Cant rename [' + tmp + '] -> [' + wad + ']', TRecordCategory.MSG_WARNING); + if ok then res := 0 else res := 2; end; procedure g_AddResource (wad, section, name: String; const data: PByte; len: Integer; out res: Integer); @@ -189,7 +217,7 @@ implementation e_WriteLog('g_AddResource "' + wad + '" "' + section + '" "' + name + '"', MSG_NOTIFY); if ext = '.wad' then g_AddResourceToDFWAD(wad, section, name, data, len, res) - else if (ext = '.pk3') or (ext = '.zip') or (ext = '.dfzip') then + else g_AddResourceToZip(wad, section, name, data, len, res) end; @@ -208,6 +236,7 @@ implementation end; f.CreateImage; f.RemoveResource(section, name); + g_DeleteFile(wad); f.SaveTo(wad); f.Free; res := 0 (* ok *) @@ -221,13 +250,14 @@ implementation tmp, path: String; ts: TFileStream; dir: array of TFileInfo; + ok: Boolean; procedure Add (name: String; data: PByte; len: Integer); var ds: TSFSMemoryChunkStream; begin SetLength(dir, n + 1); - ds := TSFSMemoryChunkStream.Create(data, len, false); - dir[n] := dfzip.ZipOne(ts, name, ds); + ds := TSFSMemoryChunkStream.Create(data, len, False); + dir[n] := dfzip.ZipOne(ts, name, ds, Compress); ds.Free; INC(n); end; @@ -248,9 +278,9 @@ implementation for i := 0 to list.Count - 1 do begin path := NoTrailing(list.Files[i].path); - if (path <> section) or (list.Files[i].name <> section) then + if (path <> section) or (list.Files[i].name <> name) then begin - g_ReadResource(wad, path, list.Files[i].name, data0, len0); + g_ReadResource(wad, win2utf(path), win2utf(list.Files[i].name), data0, len0); ASSERT(data0 <> nil); if path = '' then path := list.Files[i].name @@ -266,14 +296,11 @@ implementation dfzip.writeCentralDir(ts, dir); ts.Free; - if FileExists(wad) then - begin - if FileExists(wad + '.bak') then - ASSERT(DeleteFile(wad + '.bak')); - ASSERT(RenameFile(wad, wad + '.bak')) - end; - ASSERT(RenameFile(tmp, wad)); - res := 0 + ok := g_DeleteFile(wad); + if not ok then e_WriteLog('Cant delete older wad [' + wad + ']', TRecordCategory.MSG_WARNING); + ok := RenameFile(tmp, wad); + if not ok then e_WriteLog('ERROR: Cant rename [' + tmp + '] -> [' + wad + ']', TRecordCategory.MSG_WARNING); + if ok then res := 0 else res := 2; end; procedure g_DeleteResource (wad, section, name: String; out res: Integer); @@ -284,7 +311,7 @@ implementation ext := LowerCase(SysUtils.ExtractFileExt(wad)); if ext = '.wad' then g_DeleteResourceFromDFWAD(wad, section, name, res) - else if (ext = '.dfz') or (ext = '.pk3') or (ext = '.zip') or (ext = '.dfzip') then + else g_DeleteResourceFromZip(wad, section, name, res) end; @@ -367,12 +394,17 @@ implementation for i := 0 to len - 1 do data[i] := stream1.ReadByte(); stream1.Destroy + //stream0.Destroy (* leads to memory corruption, it destroyed with stream1? *) + end + else + begin + stream0.Destroy end end - end - else - begin - stream0.Destroy + else + begin + stream0.Destroy + end end end; SFSGCCollect