Skip to content
This repository has been archived by the owner on Apr 2, 2020. It is now read-only.

Commit

Permalink
Implement World table generation & legion support
Browse files Browse the repository at this point in the history
  • Loading branch information
Luzifix committed Jan 1, 2018
1 parent e56567f commit 9a2c64e
Show file tree
Hide file tree
Showing 11 changed files with 1,186 additions and 52 deletions.
8 changes: 8 additions & 0 deletions ADTConvert/ADTConvert.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -48,6 +49,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>ADT.ico</ApplicationIcon>
Expand All @@ -64,8 +66,12 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ConsoleConfig.cs" />
<Compile Include="IO\Extensions.cs" />
<Compile Include="Helper.cs" />
<Compile Include="IO\Files\Terrain\Wotlk\MapStructs.cs" />
<Compile Include="IO\Files\WoWTypes.cs" />
<Compile Include="Main.cs" />
<Compile Include="IO\Metrics.cs" />
<Compile Include="Program.cs" />
<Content Include="Properties\AssemblyInfo.tt">
<Generator>TextTemplatingFileGenerator</Generator>
Expand All @@ -81,6 +87,8 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="IO\SizeCache.cs" />
<Compile Include="UnsafeNativeMethods.cs" />
<Compile Include="VersionCheck\GithubRealaseModel.cs" />
<Compile Include="VersionCheck\VersionCheck.cs" />
</ItemGroup>
Expand Down
14 changes: 10 additions & 4 deletions ADTConvert/ConsoleConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class ConsoleConfig
public bool Verbose { get; set; }
public bool NoUpdate { get; set; }
public bool Watch { get; set; }
public bool Legion { get; set; }
public float LegionBoundingBox { get; set; } = 300.0f;
public bool NoTables { get; set; } = false;
public bool Help { get; set; }

private ConsoleConfig() { }
Expand All @@ -41,22 +44,25 @@ public ConsoleConfig ReadArgs(string[] args)
Verbose = (args.Contains("-v") || args.Contains("--verbose"));
NoUpdate = (args.Contains("-noUpdate") || args.Contains("--disableUpdateCheck"));
Watch = (args.Contains("-w") || args.Contains("--watch"));
Legion = (args.Contains("-l") || args.Contains("--legion"));
Help = (args.Contains("-h") || args.Contains("--help"));
NoTables = (args.Contains("-nt") || args.Contains("--noTables"));

Input = Path.GetFullPath(args[0]);

IEnumerable<string> outPath;
IEnumerable<string> boundingBox;

outPath = args.Where(s => s.StartsWith("-o="));
outPath = args.Where(s => s.StartsWith("-o=") || s.StartsWith("--output="));
if (outPath.Count() == 1)
{
Output = Path.GetFullPath(outPath.First().Split('=').Last());
}

outPath = args.Where(s => s.StartsWith("--output="));
if (Output == null && outPath.Count() == 1)
boundingBox = args.Where(s => s.StartsWith("-lb=") || s.StartsWith("--legionBoundingBox"));
if (boundingBox.Count() == 1)
{
Output = Path.GetFullPath(outPath.First().Split('=').Last());
LegionBoundingBox = Single.Parse(boundingBox.First().Split('=').Last());
}

return this;
Expand Down
5 changes: 5 additions & 0 deletions ADTConvert/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,10 @@ public static byte[] ConvertHexStringToByteArray(string hexString)

return HexAsBytes;
}

public static float ConvertClientToServer(float clientCoord)
{
return 17066 - clientCoord;
}
}
}
207 changes: 207 additions & 0 deletions ADTConvert/IO/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace ADTConvert
{
internal static unsafe class Extensions
{
public static IEnumerable<byte> HexToBytes(this string str)
{
for (var i = 0; i < str.Length; i += 2)
{
var cl = str[i + 1];
var ch = str[i];
var cnl = cl - '0';
var cnh = ch - '0';
if (cnl < 0 || cnl > 9)
{
cnl = (cl - 'a') + 10;
if (cnl < 10 || cnl > 15)
cnl = (cl - 'A') + 10;
}
if (cnh < 0 || cnh > 9)
{
cnh = (ch - 'a') + 10;
if (cnh < 10 || cnh > 15)
cnh = (ch - 'A') + 10;
}
yield return (byte)((cnh << 4) | cnl);
}
}

public static void ReadToPointer(this BinaryReader br, IntPtr dest, int size)
{
var bytes = br.ReadBytes(size);
fixed (byte* b = bytes)
UnsafeNativeMethods.CopyMemory((byte*)dest.ToPointer(), b, size);
}

public static uint ReadUInt32Be(this BinaryReader br)
{
var be = br.ReadUInt32();
return (be >> 24) | (((be >> 16) & 0xFF) << 8) | (((be >> 8) & 0xFF) << 16) | ((be & 0xFF) << 24);
}

public static string ReadWString(this BinaryReader br, long pos = -1, bool returnToOrig = true)
{
if (pos == -1)
{
StringBuilder sb = new StringBuilder();
ushort cur = br.ReadUInt16();
while (cur != 0)
{
sb.Append((char)cur);
cur = br.ReadUInt16();
}
return sb.ToString();
}
var orig = br.BaseStream.Position;
br.BaseStream.Seek(pos, SeekOrigin.Begin);

var s = ReadWString(br);

if (returnToOrig)
{
br.BaseStream.Seek(orig, SeekOrigin.Begin);
}

return s;
}

public static string ReadCString(this BinaryReader reader)
{
byte num;
List<byte> temp = new List<byte>();
while ((num = reader.ReadByte()) != 0 && reader.BaseStream.Position != reader.BaseStream.Length)
temp.Add(num);

return Encoding.UTF8.GetString(temp.ToArray());
}

public static T Read<T>(this BinaryReader br) where T : struct
{
if (SizeCache<T>.TypeRequiresMarshal)
{
throw new ArgumentException(
"Cannot read a generic structure type that requires marshaling support. Read the structure out manually.");
}

// OPTIMIZATION!
var ret = new T();
fixed (byte* b = br.ReadBytes(SizeCache<T>.Size))
{
var tPtr = (byte*)SizeCache<T>.GetUnsafePtr(ref ret);
UnsafeNativeMethods.CopyMemory(tPtr, b, SizeCache<T>.Size);
}
return ret;
}

public static T[] Read<T>(this BinaryReader br, long addr, long count) where T : struct
{
br.BaseStream.Seek(addr, SeekOrigin.Begin);
return br.Read<T>(count);
}

public static T[] Read<T>(this BinaryReader br, long count) where T : struct
{
return br.Read<T>((int)count);
}

public static T[] Read<T>(this BinaryReader br, int count) where T : struct
{
if (SizeCache<T>.TypeRequiresMarshal)
{
throw new ArgumentException(
"Cannot read a generic structure type that requires marshaling support. Read the structure out manually.");
}

if (count == 0)
return new T[0];

var ret = new T[count];
fixed (byte* pB = br.ReadBytes(SizeCache<T>.Size * count))
{
var genericPtr = (byte*)SizeCache<T>.GetUnsafePtr(ref ret[0]);
UnsafeNativeMethods.CopyMemory(genericPtr, pB, SizeCache<T>.Size * count);
}
return ret;
}

public static void Write<T>(this BinaryWriter bw, T value) where T : struct
{
if (SizeCache<T>.TypeRequiresMarshal)
{
throw new ArgumentException(
"Cannot write a generic structure type that requires marshaling support. Write the structure out manually.");
}

// fastest way to copy?
var buf = new byte[SizeCache<T>.Size];

var valData = (byte*)SizeCache<T>.GetUnsafePtr(ref value);
fixed (byte* pB = buf)
UnsafeNativeMethods.CopyMemory(pB, valData, SizeCache<T>.Size);

bw.Write(buf);
}

public static T[] ReadArray<T>(this BinaryReader br, int count) where T : struct
{
if (count == 0)
return new T[0];

if (SizeCache<T>.TypeRequiresMarshal)
throw new ArgumentException(
"Cannot read a generic structure type that requires marshaling support. Read the structure out manually.");

// NOTE: this may be safer to just call Read<T> each iteration to avoid possibilities of moved memory, etc.
// For now, we'll see if this works.
var ret = new T[count];
fixed (byte* pB = br.ReadBytes(SizeCache<T>.Size * count))
{
var genericPtr = (byte*)SizeCache<T>.GetUnsafePtr(ref ret[0]);
UnsafeNativeMethods.CopyMemory(genericPtr, pB, SizeCache<T>.Size * count);
}
return ret;
}

public static void ReadToArray<T>(this BinaryReader br, T[] data) where T : struct
{
if (SizeCache<T>.TypeRequiresMarshal)
throw new ArgumentException(
"Cannot read a generic structure type that requires marshaling support. Read the structure out manually.");

// NOTE: this may be safer to just call Read<T> each iteration to avoid possibilities of moved memory, etc.
// For now, we'll see if this works.
fixed (byte* pB = br.ReadBytes(SizeCache<T>.Size * data.Length))
{
for (int i = 0; i < data.Length; i++)
{
var tPtr = (byte*)SizeCache<T>.GetUnsafePtr(ref data[i]);
UnsafeNativeMethods.CopyMemory(tPtr, &pB[i * SizeCache<T>.Size], SizeCache<T>.Size);
}
}
}

public static void WriteArray<T>(this BinaryWriter writer, T[] values) where T : struct
{
if (values.Length == 0)
return;

if (SizeCache<T>.TypeRequiresMarshal)
throw new ArgumentException(
"Cannot write a generic structure type that requires marshaling support. Write the structure out manually.");

var buf = new byte[SizeCache<T>.Size * values.Length];
var valData = (byte*)SizeCache<T>.GetUnsafePtr(ref values[0]);

fixed (byte* ptr = buf)
UnsafeNativeMethods.CopyMemory(ptr, valData, buf.Length);

writer.Write(buf, 0, buf.Length);
}
}
}
64 changes: 64 additions & 0 deletions ADTConvert/IO/Files/Terrain/Wotlk/MapStructs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Runtime.InteropServices;

namespace ADTConvert.IO.Files.Terrain.Wotlk
{
[StructLayout(LayoutKind.Sequential)]
struct Mhdr
{
public uint Flags;
public int ofsMcin;
public int ofsMtex;
public int ofsMmdx;
public int ofsMmid;
public int ofsMwmo;
public int ofsMwid;
public int ofsMddf;
public int ofsModf;
public int ofsMfbo;
public int ofsMh2o;
public int ofsMtxf;
public int unused0, unused1, unused2, unused3;
}

[StructLayout(LayoutKind.Sequential)]
struct Mcin
{
public int OfsMcnk;
public int SizeMcnk;
public int Flags;
public int AsyncId;
}

[StructLayout(LayoutKind.Sequential)]
struct Mcnk
{
public uint Flags;
public readonly int IndexX;
public readonly int IndexY;
public int NumLayers;
public int NumDoodadRefs;
public int Mcvt;
public int Mcnr;
public int Mcly;
public int Mcrf;
public int Mcal;
public int SizeAlpha;
public int Mcsh;
public int SizeShadow;
public int AreaId;
public readonly int NumMapObjRefs;
public int Holes;
public readonly ulong Low1;
public readonly ulong Low2;
public readonly int PredTex;
public readonly int NoEffectDoodad;
public int Mcse;
public int NumSoundEmitters;
public int Mclq;
public int SizeLiquid;
public C3Vector Position;
public int Mccv;
public int Mclv;
public readonly int Unused;
}
}
Loading

0 comments on commit 9a2c64e

Please sign in to comment.