X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Feditor%2Fg_resources.pas;h=bcb7da293ab8dfda54a19c0c3142d53e657302d7;hb=b9e48f22d4c3357a3f14c47a4ec7151d811e9a12;hp=9605b1a303361b5b85a3312ccfc02ab163845520;hpb=a140ef8433c5e5cdf3d2ec4a6343c5380535e200;p=d2df-editor.git diff --git a/src/editor/g_resources.pas b/src/editor/g_resources.pas index 9605b1a..bcb7da2 100644 --- a/src/editor/g_resources.pas +++ b/src/editor/g_resources.pas @@ -3,6 +3,13 @@ unit g_resources; interface (** + g_GetResourceSection + Parse path in form 'path/to/file.wad:some/section/resouce' to + wad = 'path/to/file.wa', section = 'some/section', name = 'resource' + + g_DeleteFile + Delete file if it exists. Make backup if enabled. + g_ReadResource Read whole file from wad (data <> nil) and (len > 0) when ok @@ -26,7 +33,13 @@ interface res = 0 when ok **) + (* Editor options *) + var + Compress: Boolean; + Backup: Boolean; + procedure g_GetResourceSection (path: String; out wad, section, name: String); + procedure g_DeleteFile(wad: String; backupPostfix: String = '.bak'); 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 +97,33 @@ implementation wad := Copy(path, 1, i - 1); end; + procedure g_DeleteFile (wad: String; backupPostfix: String = '.bak'); + var newwad: String; + begin + SFSGCCollect; + SFSGCCollect; + SFSGCCollect; + if Backup then + begin + if FileExists(wad) then + begin + newwad := wad + backupPostfix; + if FileExists(newwad) then + ASSERT(DeleteFile(newwad), 'Can''t delete file ' + newwad); + ASSERT(RenameFile(wad, newwad), 'Can''t rename file ' + wad + ' -> ' + newwad) + end + end + else + begin + if FileExists(wad) then + ASSERT(DeleteFile(wad), 'Can''t delete file ' + newwad) + end + 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 @@ -124,8 +154,8 @@ implementation 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 +176,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,13 +200,8 @@ 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)); + g_DeleteFile(wad); + ASSERT(RenameFile(tmp, wad), 'Can''t rename file ' + tmp + ' -> ' + wad); res := 0 end; @@ -189,7 +214,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 +233,7 @@ implementation end; f.CreateImage; f.RemoveResource(section, name); + g_DeleteFile(wad); f.SaveTo(wad); f.Free; res := 0 (* ok *) @@ -226,8 +252,8 @@ implementation 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 +274,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,13 +292,8 @@ 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)); + g_DeleteFile(wad); + ASSERT(RenameFile(tmp, wad), 'Can''t rename file ' + tmp + ' -> ' + wad); res := 0 end; @@ -284,7 +305,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 +388,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