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.
Improved error message when loading corrupted sprites.
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:
Added GeoIP to Makefile so it is installed properly.
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");
else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
throw new NotImplementedException("Creating .Z archives is unsupported");
else if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
throw new NotImplementedException("Creating .PAK archives is unsupported");
else
return new Folder(filename, order, content);
}
@@ -77,6 +79,8 @@ namespace OpenRA.FileFormats
return new D2kSoundResources(filename, order);
else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
return new InstallShieldPackage(filename, order);
else if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
return new PakFile(filename, order);
else
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\TmpTDReader.cs" />
<Compile Include="Graphics\ShpD2Reader.cs" />
<Compile Include="FileSystem\Pak.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">