Add a Pak parser for Dune II archives.

This commit is contained in:
Paul Chote
2013-12-01 14:35:13 +13:00
parent 7fac962c09
commit 57c2e75a59
4 changed files with 103 additions and 1 deletions

View File

@@ -90,7 +90,7 @@ NEW:
Overhauled sprite loading code. Overhauled sprite loading code.
Improved error message when loading corrupted sprites. Improved error message when loading corrupted sprites.
Rewritten shp(ts) parser makes more efficient use of texture space. Rewritten shp(ts) parser makes more efficient use of texture space.
Added support for the dune 2 shp format. Added support for the dune 2 shp and pak formats.
Build system and packages: Build system and packages:
Added GeoIP to Makefile so it is installed properly. Added GeoIP to Makefile so it is installed properly.
Added desktop shortcut creation support to the Makefile and Windows installer. Added desktop shortcut creation support to the Makefile and Windows installer.

View File

@@ -57,6 +57,8 @@ namespace OpenRA.FileFormats
throw new NotImplementedException("Creating .RS archives is unsupported"); throw new NotImplementedException("Creating .RS archives is unsupported");
else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
throw new NotImplementedException("Creating .Z archives is unsupported"); throw new NotImplementedException("Creating .Z archives is unsupported");
else if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
throw new NotImplementedException("Creating .PAK archives is unsupported");
else else
return new Folder(filename, order, content); return new Folder(filename, order, content);
} }
@@ -77,6 +79,8 @@ namespace OpenRA.FileFormats
return new D2kSoundResources(filename, order); return new D2kSoundResources(filename, order);
else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
return new InstallShieldPackage(filename, order); return new InstallShieldPackage(filename, order);
else if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
return new PakFile(filename, order);
else else
return new Folder(filename, order); return new Folder(filename, order);
} }

View File

@@ -0,0 +1,97 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
namespace OpenRA.FileFormats
{
struct Entry
{
public uint Offset;
public uint Length;
public string Filename;
}
public class PakFile : IFolder
{
string filename;
int priority;
Dictionary<string, Entry> index;
Stream stream;
public PakFile(string filename, int priority)
{
this.filename = filename;
this.priority = priority;
index = new Dictionary<string, Entry>();
stream = FileSystem.Open(filename);
index = new Dictionary<string, Entry>();
var offset = stream.ReadUInt32();
while (offset != 0)
{
var file = stream.ReadASCIIZ();
var next = stream.ReadUInt32();
var length = (next == 0 ? (uint)stream.Length : next) - offset;
// Ignore duplicate files
if (index.ContainsKey(file))
continue;
index.Add(file, new Entry { Offset = offset, Length = length, Filename = file });
offset = next;
}
}
public Stream GetContent(string filename)
{
Entry entry;
if (!index.TryGetValue(filename, out entry))
return null;
stream.Seek(entry.Offset, SeekOrigin.Begin);
var data = new byte[entry.Length];
stream.Read(data, 0, (int)entry.Length);
return new MemoryStream(data);
}
public IEnumerable<uint> ClassicHashes()
{
foreach (var filename in index.Keys)
yield return PackageEntry.HashFilename(filename, PackageHashType.Classic);
}
public IEnumerable<uint> CrcHashes()
{
yield break;
}
public IEnumerable<string> AllFileNames()
{
foreach (var filename in index.Keys)
yield return filename;
}
public bool Exists(string filename)
{
return index.ContainsKey(filename);
}
public void Write(Dictionary<string, byte[]> contents)
{
throw new NotImplementedException("Cannot save Pak archives.");
}
public int Priority { get { return 1000 + priority; } }
public string Name { get { return filename; } }
}
}

View File

@@ -153,6 +153,7 @@
<Compile Include="Graphics\TmpRAReader.cs" /> <Compile Include="Graphics\TmpRAReader.cs" />
<Compile Include="Graphics\TmpTDReader.cs" /> <Compile Include="Graphics\TmpTDReader.cs" />
<Compile Include="Graphics\ShpD2Reader.cs" /> <Compile Include="Graphics\ShpD2Reader.cs" />
<Compile Include="FileSystem\Pak.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> <BootstrapperPackage Include="Microsoft.Net.Client.3.5">