Skip to content

Instantly share code, notes, and snippets.

@Citillara
Created June 13, 2019 23:30
Show Gist options
  • Save Citillara/79ce8d11ebffa4a374eb936b477148ca to your computer and use it in GitHub Desktop.
Save Citillara/79ce8d11ebffa4a374eb936b477148ca to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Tlk
{
class TlkFile
{
public TLKHeader Header;
public SortedList<int, TLKString> Strings = new SortedList<int, TLKString>();
private TlkFile() { }
public TlkFile(byte[] data)
{
byte[] entry = new byte[26];
Header = Tools.ByteArrayToStructure<TLKHeader>(data);
if (Header.Version.StartsWith("V1"))
{
Encoding enc = Encoding.GetEncoding(1252);
for (int i = 0; i < Header.NumberOfStrings; i++)
{
Array.Copy(data, 18 + i * 26, entry, 0, 26);
TLKV1Entry tlkEntry = Tools.ByteArrayToStructure<TLKV1Entry>(entry);
string s = enc.GetString(data, Header.Offset + tlkEntry.StringOffset, tlkEntry.StringLength);
Strings.Add(i, new TLKString(tlkEntry, s));
}
}
}
}
#region TLKHeader
[StructLayout(LayoutKind.Sequential, Size = 18, Pack = 1)]
public struct TLKHeader
{
/// <summary>
/// Signature ('TLK ')
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string Signature;
/// <summary>
/// Version ('V1')
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string Version;
[MarshalAs(UnmanagedType.I2)]
public Int16 Unknown;
/// <summary>
/// Number of Strref entries in this file.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public uint NumberOfStrings;
/// <summary>
/// Offset to string data
/// </summary>
[MarshalAs(UnmanagedType.I4)]
public int Offset;
}
#endregion
#region TLKV1Entry
[StructLayout(LayoutKind.Sequential, Size = 26, Pack = 1)]
public struct TLKV1Entry
{
/// <summary>
/// 2 == entry unused? (i.e. ignore other fields), 3 == normal?
/// </summary>
[MarshalAs(UnmanagedType.I2)]
public Int16 Flag;
/// <summary>
/// Resource name of the associated sound, if any
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string SoundRessourceName;
/// <summary>
/// Volume variance.
/// </summary>
[MarshalAs(UnmanagedType.I4)]
public int VolumeVariance;
/// <summary>
/// Pitch variance.
/// </summary>
[MarshalAs(UnmanagedType.I4)]
public int PitchVariance;
/// <summary>
/// Offset of this string relative to the strings section
/// </summary>
[MarshalAs(UnmanagedType.I4)]
public int StringOffset;
/// <summary>
/// length of this string
/// </summary>
[MarshalAs(UnmanagedType.I4)]
public int StringLength;
}
#endregion
class TLKString
{
public TLKV1Entry Entry;
public string Text;
public TLKString(TLKV1Entry e, string t)
{
Entry = e;
Text = t;
}
}
static class Tools
{
public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(T));
handle.Free();
return stuff;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment