Skip to content
Permalink
 
 
Cannot retrieve contributors at this time
/* Copyright (c) 2011 Rick (rick 'at' gibbed 'dot' us)
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
//-----------------------------------------------------------------------------
// Additional modifications by sephiroth99
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using Gibbed.IO;
namespace Gibbed.TombRaider.FileFormats.DRM
{
public class Resolver
{
public List<LocalDataResolver> LocalDataResolvers
= new List<LocalDataResolver>();
public List<RemoteDataResolver> RemoteDataResolvers
= new List<RemoteDataResolver>();
public List<Unknown2Resolver> Unknown2s = new List<Unknown2Resolver>();
public List<uint> Unknown3s = new List<uint>();
public List<Unknown4Resolver> Unknown4s = new List<Unknown4Resolver>();
public Stream Serialize(Endian endianness)
{
MemoryStream data = new MemoryStream();
data.WriteValueU32((uint)LocalDataResolvers.Count, endianness);
data.WriteValueU32((uint)RemoteDataResolvers.Count, endianness);
data.WriteValueU32((uint)Unknown2s.Count, endianness);
data.WriteValueU32(0, endianness); // 0 because we crashed if it was >0
data.WriteValueU32((uint)Unknown4s.Count, endianness);
foreach (LocalDataResolver r in LocalDataResolvers)
{
var val = r.Serialize();
data.WriteValueU64(val, endianness);
}
foreach (RemoteDataResolver r in RemoteDataResolvers)
{
data.WriteValueU64(r.Serialize(), endianness);
}
foreach (Unknown2Resolver r in Unknown2s)
{
data.WriteValueU32(r.Serialize(), endianness);
}
foreach (Unknown4Resolver r in Unknown4s)
{
data.WriteValueU32(r.Serialize(), endianness);
}
data.Position = 0;
return data;
}
public void Deserialize(Stream input, Endian endianness)
{
if (input.Length < 20)
{
throw new FormatException("bad section header size?");
}
var count0 = input.ReadValueU32(endianness);
var count1 = input.ReadValueU32(endianness);
var count2 = input.ReadValueU32(endianness);
var count3 = input.ReadValueU32(endianness);
var count4 = input.ReadValueU32(endianness);
this.LocalDataResolvers.Clear();
for (uint i = 0; i < count0; i++)
{
var unknown = new LocalDataResolver();
unknown.Deserialize(input);
this.LocalDataResolvers.Add(unknown);
}
this.RemoteDataResolvers.Clear();
for (uint i = 0; i < count1; i++)
{
var unknown = new RemoteDataResolver();
unknown.Deserialize(input);
this.RemoteDataResolvers.Add(unknown);
}
this.Unknown2s.Clear();
for (uint i = 0; i < count2; i++)
{
var unknown = new Unknown2Resolver();
unknown.Deserialize(input);
this.Unknown2s.Add(unknown);
}
this.Unknown3s.Clear();
if (count3 > 0)
throw new NotSupportedException();
//for (uint i = 0; i < count3; i++)
//{
// var a = input.ReadValueU32();
// this.Unknown3s.Add(a);
//}
this.Unknown4s.Clear();
for (uint i = 0; i < count4; i++)
{
var unknown = new Unknown4Resolver();
unknown.Deserialize(input);
this.Unknown4s.Add(unknown);
}
}
public class LocalDataResolver
{
public uint PointerOffset;
public uint DataOffset;
public ulong Serialize()
{
return (((ulong)this.DataOffset << 32) | (ulong)this.PointerOffset);
}
public void Deserialize(Stream input)
{
// ((value & 0xFFFFFFFF00000000) >> 32) = pointer offset
// ((value & 0x00000000FFFFFFFF) >> 0) = data offset
// buffer[pointer] = &buffer[data]
this.PointerOffset = input.ReadValueU32();
this.DataOffset = input.ReadValueU32();
}
public override string ToString()
{
return string.Format("{0:X4} {1:X8}",
this.PointerOffset,
this.DataOffset);
}
}
public class RemoteDataResolver
{
public ushort SectionIndex;
public uint PointerOffset;
public uint DataOffset;
public ulong Serialize()
{
return ( ((ulong)this.DataOffset << 38) | ((ulong)(this.PointerOffset / 4) << 14) | (ulong)this.SectionIndex );
}
public void Deserialize(Stream input)
{
// ((value & 0x0000000000003FFF) >> 0) = section index
// ((value & 0x0000003FFFFFC000) >> 14) * 4 = pointer offset
// ((value & 0xFFFFFFC000000000) >> 38) = data offset
// buffer[pointer] = &sections[index].buffer[data]
var value = input.ReadValueU64();
this.SectionIndex = (ushort)((value & 0x0000000000003FFF) >> 0);
this.PointerOffset = (uint)(((value & 0x0000003FFFFFC000) >> 14) * 4);
this.DataOffset = (uint)(((value & 0xFFFFFFC000000000) >> 38));
}
public override string ToString()
{
return string.Format("{0:X4} {1:X8} {2:X8}",
this.SectionIndex,
this.PointerOffset,
this.DataOffset);
}
}
public class Unknown2Resolver
{
public uint PointerOffset;
public byte SectionType;
public uint Serialize()
{
return ((uint)(this.SectionType << 25) | (this.PointerOffset / 4));
}
public void Deserialize(Stream input)
{
// ((value & 0x01FFFFFF) >> 0) * 4 = data dest
// ((value & 0xFE000000) >> 25) = section type
// buffer[pointer] = sections
// .Where(s.id == buffer[pointer] && s.type == type)
var value = input.ReadValueU32();
this.PointerOffset = (uint)(((value & 0x01FFFFFF) >> 0) * 4);
this.SectionType = (byte)((value & 0xFE000000) >> 25);
}
public override string ToString()
{
return string.Format("{0:X8} : {1}", this.PointerOffset, (SectionType)this.SectionType);
}
}
public class Unknown4Resolver
{
public uint PointerOffset;
public byte SectionType;
public uint Serialize()
{
return ((uint)(this.SectionType << 25) | (this.PointerOffset / 4));
}
public void Deserialize(Stream input)
{
// ((value & 0x01FFFFFF) >> 0) * 4 = data dest
// ((value & 0xFE000000) >> 25) = section type
// buffer[pointer] = sections
// .Where(s.id == buffer[pointer] && s.type == type)
var value = input.ReadValueU32();
this.PointerOffset = (uint)(((value & 0x01FFFFFF) >> 0) * 4);
this.SectionType = (byte)((value & 0xFE000000) >> 25);
}
public override string ToString()
{
return string.Format("{0:X8} : {1}", this.PointerOffset, (SectionType)this.SectionType);
}
}
}
}