This repository has been archived by the owner on Jun 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial code commit, partially working
- Loading branch information
Showing
19 changed files
with
1,373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 2013 | ||
VisualStudioVersion = 12.0.31101.0 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AuroraAssetEditor", "AuroraAssetEditor\AuroraAssetEditor.csproj", "{7EBB95B2-CB56-4263-9C2B-601E0FC36001}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|x86 = Debug|x86 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{7EBB95B2-CB56-4263-9C2B-601E0FC36001}.Debug|x86.ActiveCfg = Debug|x86 | ||
{7EBB95B2-CB56-4263-9C2B-601E0FC36001}.Debug|x86.Build.0 = Debug|x86 | ||
{7EBB95B2-CB56-4263-9C2B-601E0FC36001}.Release|x86.ActiveCfg = Release|x86 | ||
{7EBB95B2-CB56-4263-9C2B-601E0FC36001}.Release|x86.Build.0 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Application x:Class="AuroraAssetEditor.App" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
Startup="AppStart"> | ||
<Application.Resources> | ||
|
||
</Application.Resources> | ||
</Application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// | ||
// App.xaml.cs | ||
// AuroraAssetEditor | ||
// | ||
// Created by Swizzy on 04/05/2015 | ||
// Copyright (c) 2015 Swizzy. All rights reserved. | ||
|
||
namespace AuroraAssetEditor { | ||
using System.Windows; | ||
|
||
/// <summary> | ||
/// Interaction logic for App.xaml | ||
/// </summary> | ||
public partial class App { | ||
private void AppStart(object sender, StartupEventArgs e) { new MainWindow(e.Args).Show(); } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,330 @@ | ||
// | ||
// AuroraAsset.cs | ||
// AuroraAssetEditor | ||
// | ||
// Created by Swizzy on 04/05/2015 | ||
// Copyright (c) 2015 Swizzy. All rights reserved. | ||
|
||
namespace AuroraAssetEditor { | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Drawing; | ||
using System.Drawing.Imaging; | ||
using System.Linq; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
using PhoenixTools; | ||
|
||
public static class AuroraAsset { | ||
public enum AssetType { | ||
Icon, // Icon | ||
Banner, // Banner | ||
Boxart, // Cover | ||
Slot, // NXEArt, currently not used | ||
Background, // Background | ||
ScreenshotStart, // Screenshot 1 | ||
ScreenshotEnd = ScreenshotStart + ScreenShotMax, // Screenshot 20 | ||
Max = ScreenshotEnd // End of it all | ||
} | ||
|
||
private const int ScreenShotMax = 20; | ||
|
||
private static uint Swap(uint x) { return (x & 0x000000FF) << 24 | (x & 0x0000FF00) << 8 | (x & 0x00FF0000) >> 8 | (x & 0xFF000000) >> 24; } | ||
|
||
private static Image RawArgbToImage(byte[] raw, int width, int height) { | ||
var ret = new Bitmap(width, height); | ||
var rect = new Rectangle(new Point(0, 0), new Size(width, height)); | ||
var bmpData = ret.LockBits(rect, ImageLockMode.ReadWrite, ret.PixelFormat); | ||
Marshal.Copy(raw, 0, bmpData.Scan0, raw.Length); | ||
ret.UnlockBits(bmpData); | ||
return ret; | ||
} | ||
|
||
private static byte[] ImageToRawArgb(Image img) { | ||
var bmp = new Bitmap(img); | ||
var ret = new byte[bmp.Height * bmp.Width * 4]; | ||
var i = 0; | ||
for(var y = 0; y < bmp.Height; y++) { | ||
for(var x = 0; x < bmp.Width; x++) { | ||
var c = bmp.GetPixel(x, y); | ||
ret[i] = c.A; | ||
ret[i + 1] = c.R; | ||
ret[i + 2] = c.G; | ||
ret[i + 3] = c.B; | ||
i += 4; | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
public class AssetFile { | ||
public readonly int DataOffset; | ||
public readonly AssetPackEntryTable EntryTable; | ||
public readonly AssetPackHeader Header; | ||
|
||
public AssetFile() { | ||
Header = new AssetPackHeader(0x52584541, 1, 0); | ||
EntryTable = new AssetPackEntryTable(); | ||
DataOffset = 20 + (EntryTable.Entries.Length * 64); | ||
DataOffset += 2048 - (DataOffset % 2048); | ||
} | ||
|
||
public AssetFile(byte[] data) { | ||
if(data.Length < 2048) | ||
throw new Exception("Invalid asset file size!"); | ||
var magic = Swap(BitConverter.ToUInt32(data, 0)); | ||
if(magic != 0x52584541) | ||
throw new Exception("Invalid asset file magic!"); | ||
var version = Swap(BitConverter.ToUInt32(data, 4)); | ||
if(version != 1) | ||
throw new NotSupportedException("Unsupported asset file version!"); | ||
var datasize = Swap(BitConverter.ToUInt32(data, 8)); | ||
Header = new AssetPackHeader(magic, version, datasize); | ||
EntryTable = new AssetPackEntryTable(data, 12); | ||
DataOffset = 20 + (EntryTable.Entries.Length * 64); | ||
DataOffset += 2048 - (DataOffset % 2048); | ||
var offset = DataOffset; | ||
for(var i = 0; i < EntryTable.Entries.Length; i++) { | ||
if(EntryTable.Entries[i].Size <= 0) | ||
continue; | ||
var tmp = new byte[EntryTable.Entries[i].Size]; | ||
Buffer.BlockCopy(data, offset, tmp, 0, tmp.Length); | ||
SetImage(tmp, i); | ||
offset += tmp.Length; | ||
} | ||
} | ||
|
||
public int PaddingSize { get { return 0x800 - ((0x14 + EntryTable.Entries.Length * 0x40) % 0x800); } } | ||
|
||
public IEnumerable<byte> Padding { get { return new byte[PaddingSize]; } } | ||
|
||
public byte[] FileData { | ||
get { | ||
var ret = new List<byte>(); | ||
uint offset = 0; | ||
Header.DataSize = 0; | ||
EntryTable.Flags = 0; | ||
for(var i = 0; i < EntryTable.Entries.Length; i++) { | ||
var entry = EntryTable.Entries[i]; | ||
if(entry.Size <= 0) | ||
continue; | ||
entry.Offset = offset; | ||
offset += entry.Size; | ||
Header.DataSize += entry.Size; | ||
EntryTable.Flags |= (uint)(1 << i); | ||
} | ||
ret.AddRange(BitConverter.GetBytes(Swap(Header.Magic))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(Header.Version))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(Header.DataSize))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(EntryTable.Flags))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(EntryTable.ScreenshotCount))); | ||
foreach(var entry in EntryTable.Entries) { | ||
ret.AddRange(BitConverter.GetBytes(Swap(entry.Offset))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(entry.Size))); | ||
ret.AddRange(BitConverter.GetBytes(Swap(entry.ExtendedInfo))); | ||
ret.AddRange(entry.TextureHeader); | ||
} | ||
ret.AddRange(Padding); | ||
foreach(var entry in EntryTable.Entries.Where(entry => entry.Size > 0)) | ||
ret.AddRange(entry.VideoData); | ||
return ret.ToArray(); | ||
} | ||
} | ||
|
||
public bool HasBoxArt { get { return EntryTable.Entries[(int)AssetType.Boxart].Size > 0; } } | ||
|
||
public bool HasBackground { get { return EntryTable.Entries[(int)AssetType.Background].Size > 0; } } | ||
|
||
public bool HasScreenshots { get { return EntryTable.ScreenshotCount > 0; } } | ||
|
||
public bool HasIconBanner { get { return EntryTable.Entries[(int)AssetType.Icon].Size > 0 || EntryTable.Entries[(int)AssetType.Banner].Size > 0; } } | ||
|
||
private bool SetImage(Image img, int index) { | ||
if(img == null || index > (int)AssetType.Max) | ||
return false; | ||
EntryTable.Entries[index].ImageData = img; | ||
var data = ImageToRawArgb(img); | ||
byte[] video = new byte[0], header = new byte[0]; | ||
if(!AuroraAssetDll.ProcessImageToAsset(ref data, img.Width, img.Height, true, ref header, ref video)) | ||
return false; | ||
EntryTable.Entries[index].VideoData = video; | ||
EntryTable.Entries[index].TextureHeader = header; | ||
return true; | ||
} | ||
|
||
private void SetImage(byte[] videoData, int index) { | ||
var imageData = new byte[0]; | ||
int imageWidth, imageHeight; | ||
if(!AuroraAssetDll.ProcessAssetToImage(ref EntryTable.Entries[index].TextureHeader, ref videoData, ref imageData, out imageWidth, out imageHeight)) | ||
return; | ||
EntryTable.Entries[index].VideoData = videoData; | ||
EntryTable.Entries[index].ImageData = RawArgbToImage(imageData, imageWidth, imageHeight); | ||
} | ||
|
||
private void SetImage(AssetFile asset, int index) { | ||
var target = EntryTable.Entries[index]; | ||
var src = asset.EntryTable.Entries[index]; | ||
target.TextureHeader = src.TextureHeader; | ||
target.VideoData = src.VideoData; | ||
target.ImageData = src.ImageData; | ||
} | ||
|
||
public bool SetIcon(Image img) { | ||
if(img.Width != 64 || img.Height != 64) | ||
img = new Bitmap(img, new Size(64, 64)); | ||
return SetImage(img, (int)AssetType.Icon); | ||
} | ||
|
||
public bool SetBackground(Image img) { | ||
if(img.Width != 1280 || img.Height != 720) | ||
img = new Bitmap(img, new Size(1280, 720)); | ||
return SetImage(img, (int)AssetType.Background); | ||
} | ||
|
||
public bool SetBanner(Image img) { | ||
if(img.Width != 420 || img.Height != 96) | ||
img = new Bitmap(img, new Size(96, 420)); | ||
return SetImage(img, (int)AssetType.Banner); | ||
} | ||
|
||
public bool SetBoxart(Image img) { | ||
if(img.Width != 900 || img.Height != 600) | ||
img = new Bitmap(img, new Size(900, 600)); | ||
return SetImage(img, (int)AssetType.Boxart); | ||
} | ||
|
||
public bool SetScreenshot(Image img, int num) { | ||
if(img.Width != 1000 || img.Height != 562) | ||
img = new Bitmap(img, new Size(1000, 562)); | ||
num += (int)AssetType.ScreenshotStart - 1; | ||
return num <= (int)AssetType.ScreenshotEnd && SetImage(img, num); | ||
} | ||
|
||
public bool SetScreenshots(IEnumerable<Image> images) { return !images.Where((t, i) => !SetScreenshot(t, i + 1)).Any(); } | ||
|
||
public Image GetIcon() { return EntryTable.Entries[(int)AssetType.Icon].Size > 0 ? EntryTable.Entries[(int)AssetType.Icon].ImageData : null; } | ||
|
||
public Image GetBoxart() { return EntryTable.Entries[(int)AssetType.Boxart].Size > 0 ? EntryTable.Entries[(int)AssetType.Boxart].ImageData : null; } | ||
|
||
public Image GetBanner() { return EntryTable.Entries[(int)AssetType.Banner].Size > 0 ? EntryTable.Entries[(int)AssetType.Banner].ImageData : null; } | ||
|
||
public Image GetBackground() { return EntryTable.Entries[(int)AssetType.Background].Size > 0 ? EntryTable.Entries[(int)AssetType.Background].ImageData : null; } | ||
|
||
public Image GetScreenshot(int num) { | ||
num += (int)AssetType.ScreenshotStart - 1; | ||
if(num > (int)AssetType.ScreenshotEnd) | ||
return null; | ||
return EntryTable.Entries[num].Size > 0 ? EntryTable.Entries[num].ImageData : null; | ||
} | ||
|
||
public Image[] GetScreenshots() { | ||
var ret = new List<Image>(); | ||
for(var i = 0; i < ScreenShotMax; i++) | ||
ret.Add(GetScreenshot(i + 1)); | ||
return ret.ToArray(); | ||
} | ||
|
||
public void SetBoxart(AssetFile asset) { SetImage(asset, (int)AssetType.Boxart); } | ||
|
||
public void SetBackground(AssetFile asset) { SetImage(asset, (int)AssetType.Background); } | ||
|
||
public void SetIcon(AssetFile asset) { SetImage(asset, (int)AssetType.Icon); } | ||
|
||
public void SetBanner(AssetFile asset) { SetImage(asset, (int)AssetType.Banner); } | ||
|
||
public void SetScreenshots(AssetFile asset) { | ||
for(var i = (int)AssetType.ScreenshotStart; i < (int)AssetType.ScreenshotEnd; i++) | ||
SetImage(asset, i); | ||
} | ||
} | ||
|
||
public class AssetPackEntry { | ||
public Image ImageData; | ||
public byte[] TextureHeader; | ||
public byte[] VideoData; | ||
|
||
public AssetPackEntry() { | ||
Offset = 0; | ||
VideoData = new byte[0]; | ||
TextureHeader = new byte[52]; | ||
} | ||
|
||
public AssetPackEntry(byte[] data, int offset) { | ||
Offset = Swap(BitConverter.ToUInt32(data, offset)); | ||
VideoData = new byte[Swap(BitConverter.ToUInt32(data, offset + 4))]; | ||
TextureHeader = new byte[52]; | ||
Buffer.BlockCopy(data, (offset + 12), TextureHeader, 0, TextureHeader.Length); | ||
} | ||
|
||
public uint Offset { get; internal set; } | ||
|
||
public uint Size { get { return (uint)VideoData.Length; } } | ||
|
||
public uint ExtendedInfo { get { return 0; } } | ||
|
||
public Size ImageSize { get { return ImageData.Size; } } | ||
|
||
public override string ToString() { | ||
var sz = ImageSize; | ||
return string.Format("Offset: 0x{0:X}{4}Size: 0x{1:X}{4}Extended Info: 0x{2:X}{4}Texture Header Size: 0x{3:X}{4}Width: {5}{4}Height: {6}", Offset, Size, ExtendedInfo, | ||
TextureHeader.Length, Environment.NewLine, sz.Width, sz.Height); | ||
} | ||
} | ||
|
||
public class AssetPackEntryTable { | ||
public readonly AssetPackEntry[] Entries = new AssetPackEntry[(int)AssetType.Max]; | ||
|
||
public AssetPackEntryTable() { | ||
Flags = 0; | ||
ScreenshotCount = 0; | ||
for(var i = 0; i < Entries.Length; i++) | ||
Entries[i] = new AssetPackEntry(); | ||
} | ||
|
||
public AssetPackEntryTable(byte[] data, int offset) { | ||
Flags = Swap(BitConverter.ToUInt32(data, offset)); | ||
ScreenshotCount = Swap(BitConverter.ToUInt32(data, offset + 4)); | ||
offset += 8; | ||
for(var i = 0; i < Entries.Length; i++, offset += 64) | ||
Entries[i] = new AssetPackEntry(data, offset); | ||
} | ||
|
||
public uint Flags { get; internal set; } | ||
|
||
public uint ScreenshotCount { get; private set; } | ||
|
||
public override string ToString() { | ||
var sb = new StringBuilder(); | ||
sb.AppendFormat("Flags: 0x{0:X}{1}", Flags, Environment.NewLine); | ||
sb.AppendFormat("ScreenshotCount: {0}{1}", ScreenshotCount, Environment.NewLine); | ||
sb.AppendLine("Entries:"); | ||
for(var i = 0; i < Entries.Length; i++) { | ||
if(i < (int)AssetType.ScreenshotStart || i > (int)AssetType.ScreenshotEnd) | ||
sb.AppendLine(((AssetType)i) + ":"); | ||
else | ||
sb.AppendLine(string.Format("ScreenShot {0}:", i - (int)AssetType.ScreenshotStart)); | ||
sb.AppendLine(Entries[i].Size > 0 ? Entries[i].ToString() : "No data..."); | ||
} | ||
return sb.ToString(); | ||
} | ||
} | ||
|
||
public class AssetPackHeader { | ||
public AssetPackHeader(uint magic, uint version, uint dataSize) { | ||
Magic = magic; | ||
Version = version; | ||
DataSize = dataSize; | ||
} | ||
|
||
public uint Magic { get; private set; } | ||
|
||
public uint Version { get; private set; } | ||
|
||
public uint DataSize { get; internal set; } | ||
|
||
public override string ToString() { | ||
return string.Format("Magic: {0}{3}Version: {1}{3}DataSize: {2}", Encoding.ASCII.GetString(BitConverter.GetBytes(Swap(Magic))), Version, DataSize, Environment.NewLine); | ||
} | ||
} | ||
} | ||
} |
Binary file not shown.
Oops, something went wrong.