diff --git a/CustomizeMii/BNS.cs b/CustomizeMii/BNS.cs new file mode 100644 index 0000000..35bbd3a --- /dev/null +++ b/CustomizeMii/BNS.cs @@ -0,0 +1,714 @@ +/* This file is part of CustomizeMii + * Copyright (C) 2009 Leathl + * + * CustomizeMii is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CustomizeMii is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//These classes are based on bns.py of the Wii.py Framework with improvements by me (Leathl) +//Thanks to Xuzz, SquidMan, megazig, Matt_P, Omega and The Lemon Man, the authors of Wii.py! + +using System; +using System.Collections.Generic; +using System.IO; +using WaveFile; + +namespace BNS +{ + internal class BNS_Data + { + //Private Varialbes + private byte[] magic = new byte[] { (byte)'D', (byte)'A', (byte)'T', (byte)'A' }; + private UInt32 size = 0x0004d000; + private byte[] data; + + //Public Variables + public UInt32 Size { get { return size; } set { size = value; } } + public byte[] Data { get { return data; } set { data = value; } } + + public BNS_Data() { } + + public void Write(Stream outStream) + { + byte[] temp = BitConverter.GetBytes(size); Array.Reverse(temp); + + outStream.Write(magic, 0, magic.Length); + outStream.Write(temp, 0, temp.Length); + outStream.Write(data, 0, data.Length); + } + } + + internal class BNS_Info + { + //Private Variables + private byte[] magic = new byte[] { (byte)'I', (byte)'N', (byte)'F', (byte)'O' }; + private UInt32 size = 0x000000a0; + private byte codec = 0x00; + private byte hasLoop = 0x00; + private byte channelCount = 0x02; + private byte zero = 0x00; + private UInt16 sampleRate = 0xac44; + private UInt16 pad0 = 0x0000; + private UInt32 loopStart = 0x00000000; + private UInt32 loopEnd = 0x00000000; //Or total sample count + private UInt32 offsetToChannelStart = 0x00000018; + private UInt32 pad1 = 0x00000000; + private UInt32 channel1StartOffset = 0x00000020; + private UInt32 channel2StartOffset = 0x0000002C; + private UInt32 channel1Start = 0x00000000; + private UInt32 coefficients1Offset = 0x0000038; + private UInt32 pad2 = 0x00000000; + private UInt32 channel2Start = 0x00000000; + private UInt32 coefficients2Offset = 0x00000068; + private UInt32 pad3 = 0x00000000; + private int[] coefficients1 = new int[16]; + private UInt16 channel1Gain = 0x0000; + private UInt16 channel1PredictiveScale = 0x0000; + private UInt16 channel1PreviousValue = 0x0000; + private UInt16 channel1NextPreviousValue = 0x0000; + private UInt16 channel1LoopPredictiveScale = 0x0000; + private UInt16 channel1LoopPreviousValue = 0x0000; + private UInt16 channel1LoopNextPreviousValue = 0x0000; + private UInt16 channel1LoopPadding = 0x0000; + private int[] coefficients2 = new int[16]; + private UInt16 channel2Gain = 0x0000; + private UInt16 channel2PredictiveScale = 0x0000; + private UInt16 channel2PreviousValue = 0x0000; + private UInt16 channel2NextPreviousValue = 0x0000; + private UInt16 channel2LoopPredictiveScale = 0x0000; + private UInt16 channel2LoopPreviousValue = 0x0000; + private UInt16 channel2LoopNextPreviousValue = 0x0000; + private UInt16 channel2LoopPadding = 0x0000; + + //Public Variables + public byte HasLoop { get { return hasLoop; } set { hasLoop = value; } } + public UInt32 Coefficients1Offset { get { return coefficients1Offset; } set { coefficients1Offset = value; } } + public UInt32 Channel1StartOffset { get { return channel1StartOffset; } set { channel1StartOffset = value; } } + public UInt32 Channel2StartOffset { get { return channel2StartOffset; } set { channel2StartOffset = value; } } + public UInt32 Size { get { return size; } set { size = value; } } + public UInt16 SampleRate { get { return sampleRate; } set { sampleRate = value; } } + public byte ChannelCount { get { return channelCount; } set { channelCount = value; } } + public UInt32 Channel1Start { get { return channel1Start; } set { channel1Start = value; } } + public UInt32 Channel2Start { get { return channel2Start; } set { channel2Start = value; } } + public UInt32 LoopStart { get { return loopStart; } set { loopStart = value; } } + public UInt32 LoopEnd { get { return loopEnd; } set { loopEnd = value; } } + public int[] Coefficients1 { get { return coefficients1; } set { coefficients1 = value; } } + public int[] Coefficients2 { get { return coefficients2; } set { coefficients2 = value; } } + + public BNS_Info() { } + + public void Write(Stream outStream) + { + outStream.Write(magic, 0, magic.Length); + + byte[] temp = BitConverter.GetBytes(size); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + outStream.WriteByte(codec); + outStream.WriteByte(hasLoop); + outStream.WriteByte(channelCount); + outStream.WriteByte(zero); + + temp = BitConverter.GetBytes(sampleRate); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(pad0); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(loopStart); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(loopEnd); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(offsetToChannelStart); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(pad1); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1StartOffset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2StartOffset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1Start); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(coefficients1Offset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + if (this.channelCount == 2) + { + temp = BitConverter.GetBytes(pad2); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2Start); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(coefficients2Offset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(pad3); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + foreach (int thisInt in coefficients1) + { + temp = BitConverter.GetBytes(thisInt); Array.Reverse(temp); + outStream.Write(temp, 2, temp.Length - 2); + } + + temp = BitConverter.GetBytes(channel1Gain); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1PredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1PreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1NextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopNextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPadding); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + foreach (int thisInt in coefficients2) + { + temp = BitConverter.GetBytes(thisInt); Array.Reverse(temp); + outStream.Write(temp, 2, temp.Length - 2); + } + + temp = BitConverter.GetBytes(channel2Gain); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2PredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2PreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2NextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2LoopPredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2LoopPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2LoopNextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel2LoopPadding); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + } + else if (this.channelCount == 1) + { + foreach (int thisInt in coefficients1) + { + temp = BitConverter.GetBytes(thisInt); Array.Reverse(temp); + outStream.Write(temp, 2, temp.Length - 2); + } + + temp = BitConverter.GetBytes(channel1Gain); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1PredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1PreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1NextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPredictiveScale); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopNextPreviousValue); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(channel1LoopPadding); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + } + } + } + + internal class BNS_Header + { + //Private Variables + private byte[] magic = new byte[] { (byte)'B', (byte)'N', (byte)'S', (byte)' ' }; + private UInt32 flags = 0xfeff0100; + private UInt32 fileSize = 0x0004d0c0; + private UInt16 size = 0x0020; + private UInt16 chunkCount = 0x0002; + private UInt32 infoOffset = 0x00000020; + private UInt32 infoLength = 0x000000a0; + private UInt32 dataOffset = 0x000000c0; + private UInt32 dataLength = 0x0004d000; + + //Public Varialbes + public UInt32 DataOffset { get { return dataOffset; } set { dataOffset = value; } } + public UInt32 InfoLength { get { return infoLength; } set { infoLength = value; } } + public UInt16 Size { get { return size; } set { size = value; } } + public UInt32 DataLength { get { return dataLength; } set { dataLength = value; } } + public UInt32 FileSize { get { return fileSize; } set { fileSize = value; } } + + public BNS_Header() { } + + public void Write(Stream outStream) + { + outStream.Write(magic, 0, magic.Length); + + byte[] temp = BitConverter.GetBytes(flags); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(fileSize); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(size); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(chunkCount); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(infoOffset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(infoLength); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(dataOffset); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + + temp = BitConverter.GetBytes(dataLength); Array.Reverse(temp); + outStream.Write(temp, 0, temp.Length); + } + } + + public class BNS_File + { + //Private Variables + private BNS_Header bnsHeader = new BNS_Header(); + private BNS_Info bnsInfo = new BNS_Info(); + private BNS_Data bnsData = new BNS_Data(); + private int[,] lSamples = new int[2, 2]; + private int[,] rlSamples = new int[2, 2]; + private int[] tlSamples = new int[2]; + private int[] hbcDefTbl = new int[] { 674, 1040, 3598, -1738, 2270, -583, 3967, -1969, 1516, 381, 3453, -1468, 2606, -617, 3795, -1759 }; + private int[] defTbl = new int[] { 1820, -856, 3238, -1514, 2333, -550, 3336, -1376, 2444, -949, 3666, -1764, 2654, -701, 3420, -1398 }; + private int[] pHist1 = new int[2]; + private int[] pHist2 = new int[2]; + private int tempSampleCount; + private string waveFile; + private bool loopFromWave = false; + private bool converted = false; + private bool toMono = false; + + + + //Public Variables + /// + /// 0x00 (0) = No Loop, 0x01 (1) = Loop + /// + public byte HasLoop { get { return this.bnsInfo.HasLoop; } set { this.bnsInfo.HasLoop = value; } } + /// + /// The start sample of the Loop + /// + public UInt32 LoopStart { get { return this.bnsInfo.LoopStart; } set { this.bnsInfo.LoopStart = value; } } + /// + /// The total number of samples in this file + /// + public UInt32 TotalSampleCount { get { return this.bnsInfo.LoopEnd; } set { this.bnsInfo.LoopEnd = value; } } + /// + /// If true and the input Wave file is stereo, the BNS will be converted to Mono. + /// Be sure to set this before you call Convert()! + /// + public bool StereoToMono { get { return toMono; } set { toMono = value; } } + + + + //Public Functions + + public BNS_File(string waveFile) + { + this.waveFile = waveFile; + } + + public BNS_File(string waveFile, bool loopFromWave) + { + this.waveFile = waveFile; + this.loopFromWave = loopFromWave; + } + + /// + /// Returns the progress of the conversion + /// + public event EventHandler ProgressChanged; + + /// + /// Converts the Wave file to BNS + /// + public void Convert() + { + Convert(waveFile, loopFromWave); + } + + /// + /// Returns the BNS file as a Byte Array. If not already converted, it will be done first. + /// + /// + public byte[] ToByteArray() + { + return ToMemoryStream().ToArray(); + } + + /// + /// Returns the BNS file as a Memory Stream. If not already converted, it will be done first. + /// + /// + public MemoryStream ToMemoryStream() + { + if (!converted) + Convert(waveFile, loopFromWave); + + MemoryStream ms = new MemoryStream(); + + this.bnsHeader.Write(ms); + this.bnsInfo.Write(ms); + this.bnsData.Write(ms); + + return ms; + } + + /// + /// Saves the BNS file to the given path. If not already converted, it will be done first. + /// + /// + public void Save(string destionationFile) + { + if (File.Exists(destionationFile)) File.Delete(destionationFile); + + using (FileStream fs = new FileStream(destionationFile, FileMode.Create)) + { + byte[] bnsFile = ToMemoryStream().ToArray(); + fs.Write(bnsFile, 0, bnsFile.Length); + } + } + + /// + /// Sets the Loop to the given Start Sample. Be sure that you call Convert() first! + /// + /// + public void SetLoop(int loopStartSample) + { + this.bnsInfo.HasLoop = 0x01; + this.bnsInfo.LoopStart = (uint)loopStartSample; + } + + + + //Private Functions + + private void Convert(string waveFile, bool loopFromWave) + { + Wave wave = new Wave(waveFile); + int waveLoopCount = wave.LoopCount; + int waveLoopStart = wave.LoopStart; + + this.bnsInfo.ChannelCount = (byte)wave.ChannelCount; + this.bnsInfo.SampleRate = (ushort)wave.SampleRate; + + if (this.bnsInfo.ChannelCount > 2 || this.bnsInfo.ChannelCount < 1) + throw new Exception("Unsupported Count of Channels!"); + if (wave.BitDepth != 16) + throw new Exception("Only 16bit Wave files are supported!"); + if (wave.DataFormat != 1) + throw new Exception("The format of this Wave file is not supported!"); + + this.bnsData.Data = Encode(wave.GetAllFrames()); + wave.Close(); + + if (this.bnsInfo.ChannelCount == 1) + { + this.bnsHeader.InfoLength = 0x60; + this.bnsHeader.DataOffset = 0x80; + + this.bnsInfo.Size = 0x60; + this.bnsInfo.Channel1StartOffset = 0x0000001C; + this.bnsInfo.Channel2StartOffset = 0x00000000; + this.bnsInfo.Channel1Start = 0x00000028; + this.bnsInfo.Coefficients1Offset = 0x00000000; + } + + this.bnsData.Size = (uint)bnsData.Data.Length + 8; + + this.bnsHeader.DataLength = this.bnsData.Size; + this.bnsHeader.FileSize = this.bnsHeader.Size + this.bnsInfo.Size + this.bnsData.Size; + + if (loopFromWave) + if (waveLoopCount == 1) + if (waveLoopStart != -1) + { this.bnsInfo.LoopStart = (uint)waveLoopStart; this.bnsInfo.HasLoop = 0x01; } + + this.bnsInfo.LoopEnd = (uint)tempSampleCount; + + for (int i = 0; i < 16; i++) + { + this.bnsInfo.Coefficients1[i] = this.defTbl[i]; + + if (this.bnsInfo.ChannelCount == 2) + this.bnsInfo.Coefficients2[i] = this.defTbl[i]; + } + + this.converted = true; + } + + private byte[] Encode(byte[] inputFrames) + { + int offset = 0; + int[] sampleBuffer = new int[14]; + + this.tempSampleCount = inputFrames.Length / (bnsInfo.ChannelCount == 2 ? 4 : 2); + int modLength = (inputFrames.Length / (bnsInfo.ChannelCount == 2 ? 4 : 2)) % 14; + + Array.Resize(ref inputFrames, inputFrames.Length + ((14 - modLength) * (bnsInfo.ChannelCount == 2 ? 4 : 2))); + + int sampleCount = inputFrames.Length / (bnsInfo.ChannelCount == 2 ? 4 : 2); + + int blocks = (sampleCount + 13) / 14; + + List soundDataLeft = new List(); + List soundDataRight = new List(); + + int co = offset; + + if (this.toMono && this.bnsInfo.ChannelCount == 2) this.bnsInfo.ChannelCount = 1; + else if (this.toMono) this.toMono = false; + + for (int j = 0; j < sampleCount; j++) + { + soundDataLeft.Add(BitConverter.ToInt16(inputFrames, co)); + co += 2; + + if (this.bnsInfo.ChannelCount == 2 || toMono) + { + soundDataRight.Add(BitConverter.ToInt16(inputFrames, co)); + co += 2; + } + } + + byte[] data = new byte[(this.bnsInfo.ChannelCount == 2 ? (blocks * 16) : (blocks * 8))]; + + int data1Offset = 0; + int data2Offset = blocks * 8; + + this.bnsInfo.Channel2Start = (this.bnsInfo.ChannelCount == 2 ? (uint)data2Offset : 0); + + int[] leftSoundData = soundDataLeft.ToArray(); + int[] rightSoundData = soundDataRight.ToArray(); + + for (int y = 0; y < blocks; y++) + { + try + { + if (y % (int)(blocks / 100) == 0 || (y + 1) == blocks) + ChangeProgress((y + 1) * 100 / blocks); + } + catch { } + + for (int a = 0; a < 14; a++) + sampleBuffer[a] = leftSoundData[y * 14 + a]; + + byte[] outBuffer = RepackAdpcm(0, this.defTbl, sampleBuffer); + + for (int a = 0; a < 8; a++) + data[data1Offset + a] = outBuffer[a]; + + data1Offset += 8; + + if (this.bnsInfo.ChannelCount == 2) + { + for (int a = 0; a < 14; a++) + sampleBuffer[a] = rightSoundData[y * 14 + a]; + + outBuffer = RepackAdpcm(1, this.defTbl, sampleBuffer); + + for (int a = 0; a < 8; a++) + data[data2Offset + a] = outBuffer[a]; + + data2Offset += 8; + } + } + + this.bnsInfo.LoopEnd = (uint)(blocks * 7); + + return data; + } + + private byte[] RepackAdpcm(int index, int[] table, int[] inputBuffer) + { + byte[] data = new byte[8]; + int[] blSamples = new int[2]; + int bestIndex = -1; + double bestError = 999999999.0; + double error; + + for (int tableIndex = 0; tableIndex < 8; tableIndex++) + { + byte[] testData = CompressAdpcm(index, table, tableIndex, inputBuffer, out error); + + if (error < bestError) + { + bestError = error; + + for (int i = 0; i < 8; i++) + data[i] = testData[i]; + for (int i = 0; i < 2; i++) + blSamples[i] = this.tlSamples[i]; + + bestIndex = tableIndex; + } + } + + for (int i = 0; i < 2; i++) + this.rlSamples[index, i] = blSamples[i]; + + return data; + } + + private byte[] CompressAdpcm(int index, int[] table, int tableIndex, int[] inputBuffer, out double outError) + { + byte[] data = new byte[8]; + int error = 0; + int factor1 = table[2 * tableIndex + 0]; + int factor2 = table[2 * tableIndex + 1]; + + int exponent = DetermineStdExponent(index, table, tableIndex, inputBuffer); + + while (exponent <= 15) + { + bool breakIt = false; + error = 0; + data[0] = (byte)(exponent | (tableIndex << 4)); + + for (int i = 0; i < 2; i++) + this.tlSamples[i] = this.rlSamples[index, i]; + + int j = 0; + + for (int i = 0; i < 14; i++) + { + int predictor = (int)((this.tlSamples[1] * factor1 + this.tlSamples[0] * factor2) >> 11); + int residual = (inputBuffer[i] - predictor) >> exponent; + + if (residual > 7 || residual < -8) + { + exponent++; + breakIt = true; + break; + } + + int nibble = Clamp(residual, -8, 7); + + if ((i & 1) != 0) + data[i / 2 + 1] = (byte)(data[i / 2 + 1] | (nibble & 0xf)); + else + data[i / 2 + 1] = (byte)(nibble << 4); + + predictor += nibble << exponent; + + this.tlSamples[0] = this.tlSamples[1]; + this.tlSamples[1] = Clamp(predictor, -32768, 32767); + + error += (int)(Math.Pow((double)(this.tlSamples[1] - inputBuffer[i]), 2)); + } + + if (!breakIt) j = 14; + + if (j == 14) break; + } + + outError = error; + return data; + } + + private int DetermineStdExponent(int index, int[] table, int tableIndex, int[] inputBuffer) + { + int[] elSamples = new int[2]; + int maxResidual = 0; + int factor1 = table[2 * tableIndex + 0]; + int factor2 = table[2 * tableIndex + 1]; + + for (int i = 0; i < 2; i++) + elSamples[i] = this.rlSamples[index, i]; + + for (int i = 0; i < 14; i++) + { + int predictor = (elSamples[1] * factor1 + elSamples[0] * factor2) >> 11; + int residual = inputBuffer[i] - predictor; + + if (residual > maxResidual) + maxResidual = residual; + + elSamples[0] = elSamples[1]; + elSamples[1] = inputBuffer[i]; + } + + return FindExponent(maxResidual); + } + + private int FindExponent(double residual) + { + int exponent = 0; + + while (residual > 7.5 || residual < -8.5) + { + exponent++; + residual /= 2.0; + } + + return exponent; + } + + private int Clamp(int input, int min, int max) + { + if (input < min) return min; + if (input > max) return max; + return input; + } + + private void ChangeProgress(int progressPercentage) + { + EventHandler progressChanged = ProgressChanged; + if (progressChanged != null) + { + progressChanged(new object(), new System.ComponentModel.ProgressChangedEventArgs(progressPercentage, new object())); + } + } + } +} diff --git a/CustomizeMii/CustomizeMii.csproj b/CustomizeMii/CustomizeMii.csproj index bdda561..dde6bca 100644 --- a/CustomizeMii/CustomizeMii.csproj +++ b/CustomizeMii/CustomizeMii.csproj @@ -27,7 +27,7 @@ false true 0 - 1.2.0.%2a + 2.0.0.%2a false true @@ -55,12 +55,21 @@ - + + + Form + + + Form + + + CustomizeMii_BnsConvert.cs + Form @@ -88,6 +97,9 @@ + + CustomizeMii_BnsConvert.cs + CustomizeMii_ComplexForwarder.cs @@ -121,12 +133,15 @@ Settings.settings True + + + diff --git a/CustomizeMii/CustomizeMii_BackgroundWorkers.cs b/CustomizeMii/CustomizeMii_BackgroundWorkers.cs new file mode 100644 index 0000000..47060c6 --- /dev/null +++ b/CustomizeMii/CustomizeMii_BackgroundWorkers.cs @@ -0,0 +1,742 @@ +/* This file is part of CustomizeMii + * Copyright (C) 2009 Leathl + * + * CustomizeMii is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CustomizeMii is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using BNS; + +namespace CustomizeMii +{ + partial class CustomizeMii_Main + { + private bool internalSound; + + void bwBannerReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + pbProgress.Value = 100; + lbStatusText.Text = string.Empty; + SetText(tbReplace, BannerReplace); + } + + void bwBannerReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bwBannerReplace_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwBannerReplace = sender as BackgroundWorker; + string thisFile = (string)e.Argument; + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + if (Directory.Exists(TempBannerPath)) Directory.Delete(TempBannerPath, true); + + if (thisFile.EndsWith(".bin")) + { + bwBannerReplace.ReportProgress(0, "Loading banner.bin..."); + Wii.U8.UnpackU8(thisFile, TempBannerPath); + } + else if (thisFile.EndsWith(".app")) + { + bwBannerReplace.ReportProgress(0, "Loading 00000000.app..."); + Wii.U8.UnpackU8(thisFile, TempTempPath); + bwBannerReplace.ReportProgress(50, "Loading banner.bin..."); + Wii.U8.UnpackU8(TempTempPath + "meta\\banner.bin", TempBannerPath); + Directory.Delete(TempTempPath, true); + } + else + { + bwBannerReplace.ReportProgress(0, "Loading WAD..."); + Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); + if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) + throw new Exception("CustomizeMii only handles Channel WADs!"); + bwBannerReplace.ReportProgress(30, "Loading 00000000.app..."); + Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); + bwBannerReplace.ReportProgress(60, "Loading banner.bin..."); + Wii.U8.UnpackU8(TempTempPath + "00000000.app_OUT\\meta\\banner.bin", TempBannerPath); + Directory.Delete(TempTempPath, true); + } + + EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); + EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); + EventHandler AddBrlyts = new EventHandler(this.AddBrlyts); + EventHandler AddBrlans = new EventHandler(this.AddBrlans); + this.Invoke(AddBannerTpls); + this.Invoke(AddIconTpls); + this.Invoke(AddBrlyts); + this.Invoke(AddBrlans); + } + catch (Exception ex) + { + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + if (Directory.Exists(TempBannerPath)) Directory.Delete(TempBannerPath, true); + BannerReplace = string.Empty; + ErrorBox(ex.Message); + } + } + + void bwIconReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + pbProgress.Value = 100; + lbStatusText.Text = string.Empty; + SetText(tbReplace, IconReplace); + } + + void bwIconReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bwIconReplace_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwIconReplace = sender as BackgroundWorker; + string thisFile = (string)e.Argument; + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + if (Directory.Exists(TempIconPath)) Directory.Delete(TempIconPath, true); + + if (thisFile.EndsWith(".bin")) + { + bwIconReplace.ReportProgress(0, "Loading icon.bin..."); + Wii.U8.UnpackU8(thisFile, TempIconPath); + } + else if (thisFile.EndsWith(".app")) + { + bwIconReplace.ReportProgress(0, "Loading 00000000.app..."); + Wii.U8.UnpackU8(thisFile, TempTempPath); + bwIconReplace.ReportProgress(50, "Loading icon.bin..."); + Wii.U8.UnpackU8(TempTempPath + "meta\\icon.bin", TempIconPath); + Directory.Delete(TempTempPath, true); + } + else + { + bwIconReplace.ReportProgress(0, "Loading WAD..."); + Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); + if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) + throw new Exception("CustomizeMii only handles Channel WADs!"); + bwIconReplace.ReportProgress(30, "Loading 00000000.app..."); + Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); + bwIconReplace.ReportProgress(60, "Loading icon.bin..."); + Wii.U8.UnpackU8(TempTempPath + "00000000.app_OUT\\meta\\icon.bin", TempIconPath); + Directory.Delete(TempTempPath, true); + } + + EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); + EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); + EventHandler AddBrlyts = new EventHandler(this.AddBrlyts); + EventHandler AddBrlans = new EventHandler(this.AddBrlans); + this.Invoke(AddBannerTpls); + this.Invoke(AddIconTpls); + this.Invoke(AddBrlyts); + this.Invoke(AddBrlans); + } + catch (Exception ex) + { + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + if (Directory.Exists(TempIconPath)) Directory.Delete(TempIconPath, true); + IconReplace = string.Empty; + ErrorBox(ex.Message); + } + } + + void bwSoundReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + pbProgress.Value = 100; + lbStatusText.Text = string.Empty; + SetText(tbReplace, SoundReplace); + } + + void bwSoundReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bwSoundReplace_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwSoundReplace = sender as BackgroundWorker; + string thisFile = (string)e.Argument; + if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + + if (thisFile.EndsWith(".bin")) + { + bwSoundReplace.ReportProgress(0, "Copying sound.bin..."); + File.Copy(thisFile, TempSoundPath); + } + else if (thisFile.EndsWith(".app")) + { + bwSoundReplace.ReportProgress(0, "Loading 00000000.app..."); + Wii.U8.UnpackU8(thisFile, TempTempPath); + bwSoundReplace.ReportProgress(80, "Copying sound.bin..."); + File.Copy(TempTempPath + "meta\\sound.bin", TempSoundPath); + Directory.Delete(TempTempPath, true); + } + else + { + bwSoundReplace.ReportProgress(0, "Loading WAD..."); + Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); + if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) + throw new Exception("CustomizeMii only handles Channel WADs!"); + bwSoundReplace.ReportProgress(50, "Loading 00000000.app..."); + Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); + bwSoundReplace.ReportProgress(90, "Copying sound.bin..."); + File.Copy(TempTempPath + "00000000.app_OUT\\meta\\sound.bin", TempSoundPath); + Directory.Delete(TempTempPath, true); + } + + SetText(tbSound, SoundReplace); + } + catch (Exception ex) + { + if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); + if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); + SoundReplace = string.Empty; + ErrorBox(ex.Message); + } + } + + void bwConvertToBns_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (File.Exists(TempBnsPath)) + { + if (internalSound == true) + SetText(tbSound, "BNS: Internal Sound"); + else + SetText(tbSound, "BNS: " + Mp3Path); + + btnBrowseSound.Text = "Clear"; + + if (!string.IsNullOrEmpty(SoundReplace)) + { + SoundReplace = string.Empty; + if (cmbReplace.SelectedIndex == 2) SetText(tbReplace, SoundReplace); + if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); + } + } + + if (File.Exists(TempWavePath)) File.Delete(TempWavePath); + + lbStatusText.Text = string.Empty; + Mp3Path = string.Empty; + pbProgress.Value = 100; + } + + void bwConvertToBns_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + if (!string.IsNullOrEmpty((string)e.UserState)) currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bns_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + + this.Invoke(ProgressUpdate); + } + + void bwConvertToBns_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwConvertToBns = sender as BackgroundWorker; + BnsConversionInfo bnsInfo = (BnsConversionInfo)e.Argument; + string audioFile; + + if (bnsInfo.AudioFile == "Internal Sound") + { audioFile = TempWavePath; internalSound = true; } + else + audioFile = bnsInfo.AudioFile; + Mp3Path = audioFile; //Rather audioPath... + + bool mp3 = audioFile.EndsWith(".mp3"); + if (mp3 && bnsInfo.Loop == BnsConversionInfo.LoopType.FromWave) bnsInfo.Loop = BnsConversionInfo.LoopType.None; + + if (mp3) + { + bwConvertToBns.ReportProgress(0, "Converting MP3..."); + + ProcessStartInfo lameI = new ProcessStartInfo(System.Windows.Forms.Application.StartupPath + "\\lame.exe", + string.Format("--decode \"{0}\" \"{1}\"", audioFile, "C:\\cmtempmp3wav.wav")); //Gotta go this step, cause the TempWavePath is too long for lame.exe + lameI.CreateNoWindow = true; + lameI.UseShellExecute = false; + lameI.RedirectStandardError = true; + + Process lame = Process.Start(lameI); + + string thisLine = string.Empty; + while (lame.HasExited == false) + { + thisLine = lame.StandardError.ReadLine(); + if (!string.IsNullOrEmpty(thisLine)) + { + if (thisLine.StartsWith("Frame#")) + { + string thisFrame = thisLine.Remove(thisLine.IndexOf('/')); + thisFrame = thisFrame.Remove(0, thisFrame.LastIndexOf(' ') + 1); + string Frames = thisLine.Remove(0, thisLine.IndexOf('/') + 1); + Frames = Frames.Remove(Frames.IndexOf(' ')); + + int thisProgress = (int)((Convert.ToDouble(thisFrame) / Convert.ToDouble(Frames)) * 100); + bwConvertToBns.ReportProgress(thisProgress); + } + } + } + + lame.WaitForExit(); + lame.Close(); + + if (File.Exists("C:\\cmtempmp3wav.wav")) + { + FileInfo fi = new FileInfo("C:\\cmtempmp3wav.wav"); + fi.MoveTo(TempWavePath); + } + + if (!File.Exists(TempWavePath)) throw new Exception("Error converting MP3..."); + else audioFile = TempWavePath; + } + + bwConvertToBns.ReportProgress(0, "Converting To BNS..."); + + BNS_File bns = new BNS_File(audioFile, bnsInfo.Loop == BnsConversionInfo.LoopType.FromWave); + bns.ProgressChanged += new EventHandler(bns_ProgressChanged); + + bns.StereoToMono = bnsInfo.StereoToMono; + bns.Convert(); + + if (bnsInfo.Loop == BnsConversionInfo.LoopType.Manual && bnsInfo.LoopStartSample > -1 && bnsInfo.LoopStartSample < bns.TotalSampleCount) + bns.SetLoop(bnsInfo.LoopStartSample); + + bns.Save(TempBnsPath); + + if (File.Exists(TempWavePath)) + File.Delete(TempWavePath); + } + catch (Exception ex) + { + ErrorBox("Error during conversion:\n" + ex.Message); + } + } + + void bwConvertMp3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (File.Exists(TempWavePath)) + { + SetText(tbSound, Mp3Path); + + btnBrowseSound.Text = "Clear"; + + if (!string.IsNullOrEmpty(SoundReplace)) + { + SoundReplace = string.Empty; + if (cmbReplace.SelectedIndex == 2) SetText(tbReplace, SoundReplace); + if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); + } + } + + lbStatusText.Text = string.Empty; + Mp3Path = string.Empty; + pbProgress.Value = 100; + } + + void bwConvertMp3_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + + this.Invoke(ProgressUpdate); + } + + void bwConvertMp3_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwConvertMp3 = sender as BackgroundWorker; + Mp3Path = (string)e.Argument; + ProcessStartInfo lameI = new ProcessStartInfo(System.Windows.Forms.Application.StartupPath + "\\lame.exe", + string.Format("--decode \"{0}\" \"{1}\"", e.Argument, "C:\\cmtempmp3wav.wav")); //Gotta go this step, cause the TempWavePath is too long for lame.exe + lameI.CreateNoWindow = true; + lameI.UseShellExecute = false; + lameI.RedirectStandardError = true; + + Process lame = Process.Start(lameI); + + string thisLine = string.Empty; + while (lame.HasExited == false) + { + thisLine = lame.StandardError.ReadLine(); + if (!string.IsNullOrEmpty(thisLine)) + { + if (thisLine.StartsWith("Frame#")) + { + string thisFrame = thisLine.Remove(thisLine.IndexOf('/')); + thisFrame = thisFrame.Remove(0, thisFrame.LastIndexOf(' ') + 1); + string Frames = thisLine.Remove(0, thisLine.IndexOf('/') + 1); + Frames = Frames.Remove(Frames.IndexOf(' ')); + + int thisProgress = (int)((Convert.ToDouble(thisFrame) / Convert.ToDouble(Frames)) * 100); + bwConvertMp3.ReportProgress(thisProgress); + } + } + } + + lame.WaitForExit(); + lame.Close(); + + if (File.Exists("C:\\cmtempmp3wav.wav")) + { + FileInfo fi = new FileInfo("C:\\cmtempmp3wav.wav"); + fi.MoveTo(TempWavePath); + } + } + catch (Exception ex) + { + if (File.Exists(TempWavePath)) File.Delete(TempWavePath); + Mp3Path = string.Empty; + ErrorBox("Error during conversion:\n" + ex.Message); + } + } + + void bwLoadChannel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + pbProgress.Value = 100; + lbStatusText.Text = string.Empty; + } + + void bwLoadChannel_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bwLoadChannel_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwLoadChannel = sender as BackgroundWorker; + EventHandler SetSourceWad = new EventHandler(this.SetSourceWad); + byte[] WadFile = Wii.Tools.LoadFileToByteArray((string)e.Argument); + bool hashesMatch = true; + + if (Directory.Exists(TempUnpackPath)) Directory.Delete(TempUnpackPath, true); + + bwLoadChannel.ReportProgress(0, "Loading WAD..."); + Wii.WadUnpack.UnpackWad(WadFile, TempUnpackPath, out hashesMatch); + if (Wii.U8.CheckU8(TempUnpackPath + "00000000.app") == false) + throw new Exception("CustomizeMii only edits Channel WADs!"); + + this.Invoke(SetSourceWad); + + bwLoadChannel.ReportProgress(25, "Loading 00000000.app..."); + Wii.U8.UnpackU8(TempUnpackPath + "00000000.app", TempUnpackPath + "00000000.app_OUT"); + + bwLoadChannel.ReportProgress(50, "Loading banner.bin..."); + Wii.U8.UnpackU8(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin", TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT"); + + bwLoadChannel.ReportProgress(75, "Loading icon.bin..."); + Wii.U8.UnpackU8(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin", TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT"); + + bwLoadChannel.ReportProgress(90, "Gathering Information..."); + string[] ChannelTitles = Wii.WadInfo.GetChannelTitles(WadFile); + string TitleID = Wii.WadInfo.GetTitleID(WadFile, 1); + + SetText(tbAllLanguages, ChannelTitles[1]); + + if (ChannelTitles[0] != ChannelTitles[1]) + SetText(tbJapanese, ChannelTitles[0]); + if (ChannelTitles[2] != ChannelTitles[1]) + SetText(tbGerman, ChannelTitles[2]); + if (ChannelTitles[3] != ChannelTitles[1]) + SetText(tbFrench, ChannelTitles[3]); + if (ChannelTitles[4] != ChannelTitles[1]) + SetText(tbSpanish, ChannelTitles[4]); + if (ChannelTitles[5] != ChannelTitles[1]) + SetText(tbItalian, ChannelTitles[5]); + if (ChannelTitles[6] != ChannelTitles[1]) + SetText(tbDutch, ChannelTitles[6]); + + SetText(tbTitleID, TitleID); + + EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); + EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); + EventHandler AddBrlyts = new EventHandler(this.AddBrlyts); + EventHandler AddBrlans = new EventHandler(this.AddBrlans); + this.Invoke(AddBannerTpls); + this.Invoke(AddIconTpls); + this.Invoke(AddBrlyts); + this.Invoke(AddBrlans); + + bwLoadChannel.ReportProgress(100); + EventHandler EnableCtrls = new EventHandler(this.EnableControls); + this.Invoke(EnableCtrls); + + if (!hashesMatch) + System.Windows.Forms.MessageBox.Show("At least one content's hash doesn't match the hash in the TMD!\n" + + "Some files of the WAD might be corrupted, thus it might brick your Wii!", "Warning", + System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); + } + catch (Exception ex) + { + if (Directory.Exists(TempUnpackPath)) Directory.Delete(TempUnpackPath, true); + SourceWad = string.Empty; + SetText(tbSourceWad, string.Empty); + ErrorBox(ex.Message); + } + } + + void bwCreateWad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + EventHandler EnableControls = new EventHandler(this.EnableControls); + EventHandler Initialize = new EventHandler(this.Initialize); + pbProgress.Value = 100; + lbStatusText.Text = string.Empty; + this.Invoke(EnableControls); + this.Invoke(Initialize); + } + + void bwCreateWad_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + currentProgress.progressValue = e.ProgressPercentage; + currentProgress.progressState = (string)e.UserState; + + this.Invoke(ProgressUpdate); + } + + void bwCreateWad_DoWork(object sender, DoWorkEventArgs e) + { + try + { + BackgroundWorker bwCreateWad = sender as BackgroundWorker; + WadCreationInfo wadInfo = (WadCreationInfo)e.Argument; + EventHandler DisableControls = new EventHandler(this.DisableControls); + this.Invoke(DisableControls); + + bwCreateWad.ReportProgress(0, "Making TPLs transparent"); + MakeBannerTplsTransparent(); + MakeIconTplsTransparent(); + + bwCreateWad.ReportProgress(5, "Packing icon.bin..."); + byte[] iconbin; + + if (!string.IsNullOrEmpty(IconReplace)) + iconbin = Wii.U8.PackU8(TempIconPath); + else + iconbin = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT"); + + if (cbLz77.Checked == true) iconbin = Wii.Lz77.Compress(iconbin); + iconbin = Wii.U8.AddHeaderIMD5(iconbin); + Wii.Tools.SaveFileFromByteArray(iconbin, TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin"); + Directory.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT", true); + + bwCreateWad.ReportProgress(25, "Packing banner.bin..."); + byte[] bannerbin; + + if (!string.IsNullOrEmpty(BannerReplace)) + bannerbin = Wii.U8.PackU8(TempBannerPath); + else + bannerbin = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT"); + + if (cbLz77.Checked == true) bannerbin = Wii.Lz77.Compress(bannerbin); + bannerbin = Wii.U8.AddHeaderIMD5(bannerbin); + Wii.Tools.SaveFileFromByteArray(bannerbin, TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin"); + Directory.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT", true); + + if (!string.IsNullOrEmpty(SoundReplace) || !string.IsNullOrEmpty(tbSound.Text)) + { + bwCreateWad.ReportProgress(50, "Packing sound.bin..."); + + if (!string.IsNullOrEmpty(SoundReplace)) + { + File.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin"); + File.Copy(TempSoundPath, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin"); + } + else if (!string.IsNullOrEmpty(tbSound.Text)) + { + if (tbSound.Text.EndsWith(".bns")) + { + Wii.Sound.BnsToSoundBin(tbSound.Text, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", false); + } + else if (tbSound.Text.StartsWith("BNS:")) + { + Wii.Sound.BnsToSoundBin(TempBnsPath, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", false); + } + else + { + string SoundFile = tbSound.Text; + if (tbSound.Text.EndsWith(".mp3")) SoundFile = TempWavePath; + + Wii.Sound.WaveToSoundBin(SoundFile, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", false); + } + } + } + + bwCreateWad.ReportProgress(60, "Packing 00000000.app..."); + int[] Sizes = new int[3]; + string[] Titles = new string[] { tbJapanese.Text, tbEnglish.Text, tbGerman.Text, tbFrench.Text, tbSpanish.Text, tbItalian.Text, tbDutch.Text }; + + for (int i = 0; i < Titles.Length; i++) + if (string.IsNullOrEmpty(Titles[i])) Titles[i] = tbAllLanguages.Text; + + byte[] nullapp = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT", out Sizes[0], out Sizes[1], out Sizes[2]); + nullapp = Wii.U8.AddHeaderIMET(nullapp, Titles, Sizes); + Wii.Tools.SaveFileFromByteArray(nullapp, TempUnpackPath + "00000000.app"); + Directory.Delete(TempUnpackPath + "00000000.app_OUT", true); + + string[] tikfile = Directory.GetFiles(TempUnpackPath, "*.tik"); + string[] tmdfile = Directory.GetFiles(TempUnpackPath, "*.tmd"); + byte[] tmd = Wii.Tools.LoadFileToByteArray(tmdfile[0]); + + if (!string.IsNullOrEmpty(tbDol.Text)) + { + bwCreateWad.ReportProgress(80, "Inserting new DOL..."); + string[] AppFiles = Directory.GetFiles(TempUnpackPath, "*.app"); + + foreach (string thisApp in AppFiles) + if (!thisApp.EndsWith("00000000.app")) File.Delete(thisApp); + + if (wadInfo.nandLoader == 0) + { + using (BinaryReader nandloader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomizeMii.Resources.comex.app"))) + { + using (FileStream fs = new FileStream(TempUnpackPath + "\\00000001.app", FileMode.Create)) + { + byte[] temp = nandloader.ReadBytes((int)nandloader.BaseStream.Length); + fs.Write(temp, 0, temp.Length); + } + } + + if (tbDol.Text.StartsWith("Simple Forwarder:")) + { + CreateForwarderSimple(TempUnpackPath + "\\00000002.app"); + } + else if (tbDol.Text.StartsWith("Complex Forwarder:")) + { + bwCreateWad.ReportProgress(82, "Compiling Forwarder..."); + CreateForwarderComplex(TempUnpackPath + "\\00000002.app"); + } + else if (tbDol.Text == "Internal" || tbDol.Text.EndsWith(".wad")) + { + File.Copy(TempDolPath, TempUnpackPath + "\\00000002.app"); + } + else + { + File.Copy(tbDol.Text, TempUnpackPath + "\\00000002.app"); + } + + tmd = Wii.WadEdit.ChangeTmdBootIndex(tmd, 1); + } + else + { + using (BinaryReader nandloader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomizeMii.Resources.Waninkoko.app"))) + { + using (FileStream fs = new FileStream(TempUnpackPath + "\\00000002.app", FileMode.Create)) + { + byte[] temp = nandloader.ReadBytes((int)nandloader.BaseStream.Length); + fs.Write(temp, 0, temp.Length); + } + } + + if (tbDol.Text.StartsWith("Simple Forwarder:")) + { + CreateForwarderSimple(TempUnpackPath + "\\00000001.app"); + } + else if (tbDol.Text.StartsWith("Complex Forwarder:")) + { + bwCreateWad.ReportProgress(82, "Compiling Forwarder..."); + CreateForwarderComplex(TempUnpackPath + "\\00000001.app"); + } + else if (tbDol.Text == "Internal") + { + File.Copy(TempDolPath, TempUnpackPath + "\\00000001.app"); + } + else + { + File.Copy(tbDol.Text, TempUnpackPath + "\\00000001.app"); + } + + tmd = Wii.WadEdit.ChangeTmdBootIndex(tmd, 2); + } + + tmd = Wii.WadEdit.ChangeTmdContentCount(tmd, 3); + + bwCreateWad.ReportProgress(85, "Updating TMD..."); + File.Delete(tmdfile[0]); + using (FileStream fs = new FileStream(tmdfile[0], FileMode.Create)) + { + byte[] tmdconts = new byte[108]; + tmdconts[7] = 0x01; + tmdconts[39] = 0x01; + tmdconts[41] = 0x01; + tmdconts[43] = 0x01; + tmdconts[75] = 0x02; + tmdconts[77] = 0x02; + tmdconts[79] = 0x01; + + fs.Write(tmd, 0, 484); + fs.Write(tmdconts, 0, tmdconts.Length); + } + } + + bwCreateWad.ReportProgress(85, "Updating TMD..."); + Wii.WadEdit.UpdateTmdContents(tmdfile[0]); + + Wii.WadEdit.ChangeTitleID(tikfile[0], 0, tbTitleID.Text.ToUpper()); + Wii.WadEdit.ChangeTitleID(tmdfile[0], 1, tbTitleID.Text.ToUpper()); + + bwCreateWad.ReportProgress(90, "Trucha Signing..."); + Wii.WadEdit.TruchaSign(tmdfile[0], 1); + Wii.WadEdit.TruchaSign(tikfile[0], 0); + + bwCreateWad.ReportProgress(95, "Packing WAD..."); + if (File.Exists(wadInfo.outFile)) File.Delete(wadInfo.outFile); + Wii.WadPack.PackWad(TempUnpackPath, wadInfo.outFile, false); + + bwCreateWad.ReportProgress(100, " "); + CreationTimer.Stop(); + + FileInfo fi = new FileInfo(wadInfo.outFile); + double fileSize = Math.Round(fi.Length * 0.0009765625 * 0.0009765625, 2); + + InfoBox(string.Format("Successfully created custom channel!\nTime elapsed: {0} ms\nFilesize: {1} MB\nApprox. Blocks: {2}", CreationTimer.ElapsedMilliseconds, fileSize, Wii.WadInfo.GetNandBlocks(wadInfo.outFile))); + } + catch (Exception ex) + { + CreationTimer.Stop(); + EventHandler EnableControls = new EventHandler(this.EnableControls); + this.Invoke(EnableControls); + ErrorBox(ex.Message); + } + } + } +} diff --git a/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs b/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs new file mode 100644 index 0000000..8faf26e --- /dev/null +++ b/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs @@ -0,0 +1,391 @@ +/* This file is part of CustomizeMii + * Copyright (C) 2009 Leathl + * + * CustomizeMii is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CustomizeMii is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace CustomizeMii +{ + partial class CustomizeMii_BnsConvert + { + /// + /// Erforderliche Designervariable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Verwendete Ressourcen bereinigen. + /// + /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Windows Form-Designer generierter Code + + /// + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// + private void InitializeComponent() + { + this.btnCancel = new System.Windows.Forms.Button(); + this.btnConvert = new System.Windows.Forms.Button(); + this.lbAudioFile = new System.Windows.Forms.Label(); + this.tbAudioFile = new System.Windows.Forms.TextBox(); + this.btnBrowseAudioFile = new System.Windows.Forms.Button(); + this.gbLoop = new System.Windows.Forms.GroupBox(); + this.tbLoopStart = new System.Windows.Forms.TextBox(); + this.rbEnterManually = new System.Windows.Forms.RadioButton(); + this.rbFromAudioFile = new System.Windows.Forms.RadioButton(); + this.rbNone = new System.Windows.Forms.RadioButton(); + this.gbWaveInfo = new System.Windows.Forms.GroupBox(); + this.lbStatusValue = new System.Windows.Forms.Label(); + this.lbLoopStartValue = new System.Windows.Forms.Label(); + this.lbLoopCountValue = new System.Windows.Forms.Label(); + this.lbFormatValue = new System.Windows.Forms.Label(); + this.lbChannelCountValue = new System.Windows.Forms.Label(); + this.lbSamplerateValue = new System.Windows.Forms.Label(); + this.lbBitdepthValue = new System.Windows.Forms.Label(); + this.lbStatus = new System.Windows.Forms.Label(); + this.lbLoopStart = new System.Windows.Forms.Label(); + this.lbLoopCount = new System.Windows.Forms.Label(); + this.lbFormat = new System.Windows.Forms.Label(); + this.lbChannelCount = new System.Windows.Forms.Label(); + this.lbSamplerate = new System.Windows.Forms.Label(); + this.lbBitdepth = new System.Windows.Forms.Label(); + this.cbSourceSound = new System.Windows.Forms.CheckBox(); + this.gbLoop.SuspendLayout(); + this.gbWaveInfo.SuspendLayout(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(186, 179); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(160, 23); + this.btnCancel.TabIndex = 10; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnConvert + // + this.btnConvert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnConvert.Location = new System.Drawing.Point(15, 179); + this.btnConvert.Name = "btnConvert"; + this.btnConvert.Size = new System.Drawing.Size(160, 23); + this.btnConvert.TabIndex = 9; + this.btnConvert.Text = "Convert"; + this.btnConvert.UseVisualStyleBackColor = true; + this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click); + // + // lbAudioFile + // + this.lbAudioFile.AutoSize = true; + this.lbAudioFile.Location = new System.Drawing.Point(12, 24); + this.lbAudioFile.Name = "lbAudioFile"; + this.lbAudioFile.Size = new System.Drawing.Size(56, 13); + this.lbAudioFile.TabIndex = 11; + this.lbAudioFile.Text = "Audio File:"; + // + // tbAudioFile + // + this.tbAudioFile.Location = new System.Drawing.Point(74, 21); + this.tbAudioFile.Name = "tbAudioFile"; + this.tbAudioFile.ReadOnly = true; + this.tbAudioFile.Size = new System.Drawing.Size(191, 20); + this.tbAudioFile.TabIndex = 12; + // + // btnBrowseAudioFile + // + this.btnBrowseAudioFile.Location = new System.Drawing.Point(271, 20); + this.btnBrowseAudioFile.Name = "btnBrowseAudioFile"; + this.btnBrowseAudioFile.Size = new System.Drawing.Size(75, 23); + this.btnBrowseAudioFile.TabIndex = 13; + this.btnBrowseAudioFile.Text = "Browse..."; + this.btnBrowseAudioFile.UseVisualStyleBackColor = true; + this.btnBrowseAudioFile.Click += new System.EventHandler(this.btnBrowseAudioFile_Click); + // + // gbLoop + // + this.gbLoop.Controls.Add(this.tbLoopStart); + this.gbLoop.Controls.Add(this.rbEnterManually); + this.gbLoop.Controls.Add(this.rbFromAudioFile); + this.gbLoop.Controls.Add(this.rbNone); + this.gbLoop.Location = new System.Drawing.Point(15, 72); + this.gbLoop.Name = "gbLoop"; + this.gbLoop.Size = new System.Drawing.Size(331, 94); + this.gbLoop.TabIndex = 14; + this.gbLoop.TabStop = false; + this.gbLoop.Text = "Loop"; + // + // tbLoopStart + // + this.tbLoopStart.Enabled = false; + this.tbLoopStart.Location = new System.Drawing.Point(227, 64); + this.tbLoopStart.Name = "tbLoopStart"; + this.tbLoopStart.Size = new System.Drawing.Size(60, 20); + this.tbLoopStart.TabIndex = 1; + this.tbLoopStart.Text = "0"; + // + // rbEnterManually + // + this.rbEnterManually.AutoSize = true; + this.rbEnterManually.Location = new System.Drawing.Point(6, 65); + this.rbEnterManually.Name = "rbEnterManually"; + this.rbEnterManually.Size = new System.Drawing.Size(215, 17); + this.rbEnterManually.TabIndex = 0; + this.rbEnterManually.Text = "Enter Manually Loop Start Sample:"; + this.rbEnterManually.UseVisualStyleBackColor = true; + this.rbEnterManually.CheckedChanged += new System.EventHandler(this.rbSelectionChanged); + // + // rbFromAudioFile + // + this.rbFromAudioFile.AutoSize = true; + this.rbFromAudioFile.Location = new System.Drawing.Point(6, 42); + this.rbFromAudioFile.Name = "rbFromAudioFile"; + this.rbFromAudioFile.Size = new System.Drawing.Size(281, 17); + this.rbFromAudioFile.TabIndex = 0; + this.rbFromAudioFile.Text = "From Audio File (works only with pre-looped wave files)"; + this.rbFromAudioFile.UseVisualStyleBackColor = true; + this.rbFromAudioFile.CheckedChanged += new System.EventHandler(this.rbSelectionChanged); + // + // rbNone + // + this.rbNone.AutoSize = true; + this.rbNone.Checked = true; + this.rbNone.Location = new System.Drawing.Point(6, 19); + this.rbNone.Name = "rbNone"; + this.rbNone.Size = new System.Drawing.Size(51, 17); + this.rbNone.TabIndex = 0; + this.rbNone.TabStop = true; + this.rbNone.Text = "None"; + this.rbNone.UseVisualStyleBackColor = true; + this.rbNone.CheckedChanged += new System.EventHandler(this.rbSelectionChanged); + // + // gbWaveInfo + // + this.gbWaveInfo.Controls.Add(this.lbStatusValue); + this.gbWaveInfo.Controls.Add(this.lbLoopStartValue); + this.gbWaveInfo.Controls.Add(this.lbLoopCountValue); + this.gbWaveInfo.Controls.Add(this.lbFormatValue); + this.gbWaveInfo.Controls.Add(this.lbChannelCountValue); + this.gbWaveInfo.Controls.Add(this.lbSamplerateValue); + this.gbWaveInfo.Controls.Add(this.lbBitdepthValue); + this.gbWaveInfo.Controls.Add(this.lbStatus); + this.gbWaveInfo.Controls.Add(this.lbLoopStart); + this.gbWaveInfo.Controls.Add(this.lbLoopCount); + this.gbWaveInfo.Controls.Add(this.lbFormat); + this.gbWaveInfo.Controls.Add(this.lbChannelCount); + this.gbWaveInfo.Controls.Add(this.lbSamplerate); + this.gbWaveInfo.Controls.Add(this.lbBitdepth); + this.gbWaveInfo.Location = new System.Drawing.Point(363, 20); + this.gbWaveInfo.Name = "gbWaveInfo"; + this.gbWaveInfo.Size = new System.Drawing.Size(135, 182); + this.gbWaveInfo.TabIndex = 15; + this.gbWaveInfo.TabStop = false; + this.gbWaveInfo.Text = "Wave Info"; + // + // lbStatusValue + // + this.lbStatusValue.Location = new System.Drawing.Point(75, 151); + this.lbStatusValue.Name = "lbStatusValue"; + this.lbStatusValue.Size = new System.Drawing.Size(54, 13); + this.lbStatusValue.TabIndex = 7; + // + // lbLoopStartValue + // + this.lbLoopStartValue.Location = new System.Drawing.Point(75, 130); + this.lbLoopStartValue.Name = "lbLoopStartValue"; + this.lbLoopStartValue.Size = new System.Drawing.Size(54, 13); + this.lbLoopStartValue.TabIndex = 7; + // + // lbLoopCountValue + // + this.lbLoopCountValue.Location = new System.Drawing.Point(75, 109); + this.lbLoopCountValue.Name = "lbLoopCountValue"; + this.lbLoopCountValue.Size = new System.Drawing.Size(54, 13); + this.lbLoopCountValue.TabIndex = 7; + // + // lbFormatValue + // + this.lbFormatValue.Location = new System.Drawing.Point(75, 88); + this.lbFormatValue.Name = "lbFormatValue"; + this.lbFormatValue.Size = new System.Drawing.Size(54, 13); + this.lbFormatValue.TabIndex = 7; + // + // lbChannelCountValue + // + this.lbChannelCountValue.Location = new System.Drawing.Point(75, 67); + this.lbChannelCountValue.Name = "lbChannelCountValue"; + this.lbChannelCountValue.Size = new System.Drawing.Size(54, 13); + this.lbChannelCountValue.TabIndex = 7; + // + // lbSamplerateValue + // + this.lbSamplerateValue.Location = new System.Drawing.Point(75, 46); + this.lbSamplerateValue.Name = "lbSamplerateValue"; + this.lbSamplerateValue.Size = new System.Drawing.Size(54, 13); + this.lbSamplerateValue.TabIndex = 7; + // + // lbBitdepthValue + // + this.lbBitdepthValue.Location = new System.Drawing.Point(75, 25); + this.lbBitdepthValue.Name = "lbBitdepthValue"; + this.lbBitdepthValue.Size = new System.Drawing.Size(54, 13); + this.lbBitdepthValue.TabIndex = 7; + // + // lbStatus + // + this.lbStatus.AutoSize = true; + this.lbStatus.Location = new System.Drawing.Point(6, 151); + this.lbStatus.Name = "lbStatus"; + this.lbStatus.Size = new System.Drawing.Size(40, 13); + this.lbStatus.TabIndex = 6; + this.lbStatus.Text = "Status:"; + // + // lbLoopStart + // + this.lbLoopStart.AutoSize = true; + this.lbLoopStart.Location = new System.Drawing.Point(6, 130); + this.lbLoopStart.Name = "lbLoopStart"; + this.lbLoopStart.Size = new System.Drawing.Size(59, 13); + this.lbLoopStart.TabIndex = 5; + this.lbLoopStart.Text = "Loop Start:"; + // + // lbLoopCount + // + this.lbLoopCount.AutoSize = true; + this.lbLoopCount.Location = new System.Drawing.Point(6, 109); + this.lbLoopCount.Name = "lbLoopCount"; + this.lbLoopCount.Size = new System.Drawing.Size(39, 13); + this.lbLoopCount.TabIndex = 4; + this.lbLoopCount.Text = "Loops:"; + // + // lbFormat + // + this.lbFormat.AutoSize = true; + this.lbFormat.Location = new System.Drawing.Point(6, 88); + this.lbFormat.Name = "lbFormat"; + this.lbFormat.Size = new System.Drawing.Size(42, 13); + this.lbFormat.TabIndex = 3; + this.lbFormat.Text = "Format:"; + // + // lbChannelCount + // + this.lbChannelCount.AutoSize = true; + this.lbChannelCount.Location = new System.Drawing.Point(6, 67); + this.lbChannelCount.Name = "lbChannelCount"; + this.lbChannelCount.Size = new System.Drawing.Size(54, 13); + this.lbChannelCount.TabIndex = 2; + this.lbChannelCount.Text = "Channels:"; + // + // lbSamplerate + // + this.lbSamplerate.AutoSize = true; + this.lbSamplerate.Location = new System.Drawing.Point(6, 46); + this.lbSamplerate.Name = "lbSamplerate"; + this.lbSamplerate.Size = new System.Drawing.Size(63, 13); + this.lbSamplerate.TabIndex = 1; + this.lbSamplerate.Text = "Samplerate:"; + // + // lbBitdepth + // + this.lbBitdepth.AutoSize = true; + this.lbBitdepth.Location = new System.Drawing.Point(6, 25); + this.lbBitdepth.Name = "lbBitdepth"; + this.lbBitdepth.Size = new System.Drawing.Size(49, 13); + this.lbBitdepth.TabIndex = 0; + this.lbBitdepth.Text = "Bitdepth:"; + // + // cbSourceSound + // + this.cbSourceSound.AutoSize = true; + this.cbSourceSound.Enabled = false; + this.cbSourceSound.Location = new System.Drawing.Point(15, 50); + this.cbSourceSound.Name = "cbSourceSound"; + this.cbSourceSound.Size = new System.Drawing.Size(170, 17); + this.cbSourceSound.TabIndex = 16; + this.cbSourceSound.Text = "Take sound from source WAD"; + this.cbSourceSound.UseVisualStyleBackColor = true; + this.cbSourceSound.CheckedChanged += new System.EventHandler(this.cbSourceSound_CheckedChanged); + // + // CustomizeMii_BnsConvert + // + this.AcceptButton = this.btnConvert; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(510, 220); + this.Controls.Add(this.cbSourceSound); + this.Controls.Add(this.gbWaveInfo); + this.Controls.Add(this.gbLoop); + this.Controls.Add(this.btnBrowseAudioFile); + this.Controls.Add(this.tbAudioFile); + this.Controls.Add(this.lbAudioFile); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnConvert); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "CustomizeMii_BnsConvert"; + this.Text = "CustomizeMii_BnsConvert"; + this.Load += new System.EventHandler(this.CustomizeMii_BnsConvert_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CustomizeMii_BnsConvert_FormClosing); + this.gbLoop.ResumeLayout(false); + this.gbLoop.PerformLayout(); + this.gbWaveInfo.ResumeLayout(false); + this.gbWaveInfo.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnConvert; + private System.Windows.Forms.Label lbAudioFile; + private System.Windows.Forms.TextBox tbAudioFile; + private System.Windows.Forms.Button btnBrowseAudioFile; + private System.Windows.Forms.GroupBox gbLoop; + private System.Windows.Forms.RadioButton rbNone; + private System.Windows.Forms.RadioButton rbEnterManually; + private System.Windows.Forms.RadioButton rbFromAudioFile; + private System.Windows.Forms.TextBox tbLoopStart; + private System.Windows.Forms.GroupBox gbWaveInfo; + private System.Windows.Forms.Label lbBitdepth; + private System.Windows.Forms.Label lbSamplerate; + private System.Windows.Forms.Label lbChannelCount; + private System.Windows.Forms.Label lbFormat; + private System.Windows.Forms.Label lbLoopCount; + private System.Windows.Forms.Label lbLoopStart; + private System.Windows.Forms.Label lbStatus; + private System.Windows.Forms.Label lbStatusValue; + private System.Windows.Forms.Label lbLoopStartValue; + private System.Windows.Forms.Label lbLoopCountValue; + private System.Windows.Forms.Label lbFormatValue; + private System.Windows.Forms.Label lbChannelCountValue; + private System.Windows.Forms.Label lbSamplerateValue; + private System.Windows.Forms.Label lbBitdepthValue; + private System.Windows.Forms.CheckBox cbSourceSound; + + } +} \ No newline at end of file diff --git a/CustomizeMii/CustomizeMii_BnsConvert.cs b/CustomizeMii/CustomizeMii_BnsConvert.cs new file mode 100644 index 0000000..8bdf4b6 --- /dev/null +++ b/CustomizeMii/CustomizeMii_BnsConvert.cs @@ -0,0 +1,356 @@ +/* This file is part of CustomizeMii + * Copyright (C) 2009 Leathl + * + * CustomizeMii is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CustomizeMii is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; +using System.IO; +using System.Windows.Forms; +using System.ComponentModel; +using WaveFile; + +namespace CustomizeMii +{ + public partial class CustomizeMii_BnsConvert : Form + { + private bool lameExists; + private int loopStartSample; + private BackgroundWorker bwGatherInfo; + private int bitDepth; + private int sampleRate; + private int channelCount; + private int dataFormat; + private int loopCount; + private int loopStart; + private bool error = false; + private bool cancelled = false; + + public string AudioFile { get { return tbAudioFile.Text; } } + public bool LoopNone { get { return rbNone.Checked; } } + public bool LoopFromAudio { get { return rbFromAudioFile.Checked; } } + public bool LoopManually { get { return rbEnterManually.Checked; } } + public int LoopStartSample { get { return loopStartSample; } } + public int ChannelCount { get { return channelCount; } } + + public CustomizeMii_BnsConvert(bool lameExists) + { + InitializeComponent(); + this.lameExists = lameExists; + } + + private void CustomizeMii_BnsConvert_Load(object sender, EventArgs e) + { + //this.Size = new System.Drawing.Size(358, 220); + this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, 220); + + this.CenterToParent(); + bwGatherInfo = new BackgroundWorker(); + bwGatherInfo.WorkerSupportsCancellation = true; + + bwGatherInfo.DoWork += new DoWorkEventHandler(bwGatherInfo_DoWork); + + byte[] soundBin = Wii.Tools.LoadFileToByteArray(CustomizeMii_Main.TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", 32, 16); + + if (soundBin[0] == 'R' && soundBin[1] == 'I' && soundBin[2] == 'F' && soundBin[3] == 'F') + { cbSourceSound.Enabled = true; } + else if (soundBin[0] == 'L' && soundBin[1] == 'Z' && soundBin[2] == '7' && soundBin[3] == '7') + if (soundBin[9] == 'R' && soundBin[10] == 'I' && soundBin[11] == 'F' && soundBin[12] == 'F') + { cbSourceSound.Enabled = true; } + } + + private void CustomizeMii_BnsConvert_FormClosing(object sender, FormClosingEventArgs e) + { + cancelled = true; + + if (bwGatherInfo.IsBusy) + bwGatherInfo.CancelAsync(); + } + + private void rbSelectionChanged(object sender, EventArgs e) + { + tbLoopStart.Enabled = rbEnterManually.Checked; + } + + private void btnConvert_Click(object sender, EventArgs e) + { + if (!File.Exists(tbAudioFile.Text) && tbAudioFile.Text != "Internal Sound") + { + tbAudioFile.Focus(); + tbAudioFile.SelectAll(); + return; + } + + if (!int.TryParse(tbLoopStart.Text, out loopStartSample)) + { + tbLoopStart.Focus(); + tbLoopStart.SelectAll(); + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void cbSourceSound_CheckedChanged(object sender, EventArgs e) + { + if (cbSourceSound.Checked) + { + tbAudioFile.Text = "Internal Sound"; + + FileStream fs = new FileStream(CustomizeMii_Main.TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", FileMode.Open); + byte[] audio = new byte[fs.Length - 32]; + int offset = 0; + + fs.Seek(32, SeekOrigin.Begin); + fs.Read(audio, 0, audio.Length); + fs.Close(); + + if ((offset = Wii.Lz77.GetLz77Offset(audio)) != -1) + audio = Wii.Lz77.Decompress(audio, offset); + + foreach (Label thisLabel in gbWaveInfo.Controls) + if (thisLabel.Name.ToLower().Contains("value")) + { + thisLabel.ForeColor = System.Drawing.Color.Black; + thisLabel.Text = "Gathering"; + } + + bwGatherInfo.RunWorkerAsync(audio); + + //this.Size = new System.Drawing.Size(510, 220); + this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, 220); + } + else + { + if (tbAudioFile.Text == "Internal Sound") + tbAudioFile.Text = string.Empty; + + //this.Size = new System.Drawing.Size(358, 220); + this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, 220); + } + } + + private void btnBrowseAudioFile_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + if (lameExists) + { ofd.Filter = "Wave|*.wav|MP3|*.mp3|All|*.wav;*.mp3"; ofd.FilterIndex = 3; } + else + { ofd.Filter = "Wave|*.wav"; } + + if (ofd.ShowDialog() == DialogResult.OK) + { + if (ofd.FileName != tbAudioFile.Text) + { + btnConvert.Enabled = false; + + cbSourceSound.Checked = false; + tbAudioFile.Text = ofd.FileName; + + if (ofd.FileName.EndsWith(".wav")) + { + rbFromAudioFile.Enabled = true; + + foreach (Label thisLabel in gbWaveInfo.Controls) + if (thisLabel.Name.ToLower().Contains("value")) + { + thisLabel.ForeColor = System.Drawing.Color.Black; + thisLabel.Text = "Gathering"; + } + + bwGatherInfo.RunWorkerAsync(ofd.FileName); + + //this.Size = new System.Drawing.Size(510, 220); + this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, 220); + } + else if (ofd.FileName.EndsWith(".mp3")) + { + channelCount = 0; + btnConvert.Enabled = true; + + if (rbFromAudioFile.Checked) rbNone.Checked = true; + rbFromAudioFile.Enabled = false; + + //this.Size = new System.Drawing.Size(358, 220); + this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, 220); + } + } + } + } + + void bwGatherInfo_DoWork(object sender, DoWorkEventArgs e) + { + EventHandler UpdateValues = new EventHandler(this.UpdateValues); + + try + { + Wave wave; + if (e.Argument is byte[]) + { wave = new Wave((byte[])e.Argument); } + else + { wave = new Wave((string)e.Argument); } + + try { bitDepth = wave.BitDepth; } + catch { bitDepth = -1; } + + try { sampleRate = wave.SampleRate; } + catch { sampleRate = -1; } + + try { channelCount = wave.ChannelCount; } + catch { channelCount = -1; } + + try { dataFormat = wave.DataFormat; } + catch { dataFormat = -1; } + + try { loopCount = wave.LoopCount; } + catch { loopCount = -1; } + + try { loopStart = wave.LoopStart; } + catch { loopStart = -1; } + + if (!cancelled) + this.Invoke(UpdateValues); + + if (e.Argument is byte[]) + { + byte[] audio = e.Argument as byte[]; + using (FileStream fs = new FileStream(CustomizeMii_Main.TempWavePath, FileMode.Create)) + { + fs.Write(audio, 0, audio.Length); + } + } + } + catch + { + error = true; + + if (!cancelled) + this.Invoke(UpdateValues); + } + } + + void UpdateValues(object sender, EventArgs e) + { + if (error == true) + { + foreach (Label thisLabel in gbWaveInfo.Controls) + if (thisLabel.Name.ToLower().Contains("value")) + { + thisLabel.Text = "Error"; + thisLabel.ForeColor = System.Drawing.Color.Red; + } + + error = false; + return; + } + + bool statusOk = true; + + if (bitDepth == -1) lbBitdepthValue.Text = "Error"; + else lbBitdepthValue.Text = bitDepth.ToString(); + + if (sampleRate == -1) lbSamplerateValue.Text = "Error"; + else lbSamplerateValue.Text = sampleRate.ToString(); + + if (dataFormat == -1) lbFormatValue.Text = "Error"; + else if (dataFormat == 1) lbFormatValue.Text = "1 (PCM)"; + else lbFormatValue.Text = dataFormat.ToString(); + + if (channelCount == -1) lbChannelCountValue.Text = "Error"; + else if (channelCount == 1) lbChannelCountValue.Text = "1 (Mono)"; + else if (channelCount == 2) lbChannelCountValue.Text = "2 (Stereo)"; + else lbChannelCountValue.Text = channelCount.ToString(); + + if (loopCount == -1) lbLoopCountValue.Text = "Error"; + else lbLoopCountValue.Text = loopCount.ToString(); + + if (loopCount == -1) lbLoopStartValue.Text = "Error"; + else if (loopCount == 1) { lbLoopStartValue.Text = loopStart == -1 ? "Error" : loopStart.ToString(); } + else lbLoopStartValue.Text = "-"; + + + + if (lbBitdepthValue.Text == "Error" || bitDepth != 16) + { + lbBitdepthValue.ForeColor = System.Drawing.Color.Red; + statusOk = false; + } + else lbBitdepthValue.ForeColor = System.Drawing.Color.Green; + + if (lbSamplerateValue.Text == "Error") + { + lbSamplerateValue.ForeColor = System.Drawing.Color.Red; + statusOk = false; + } + else lbSamplerateValue.ForeColor = System.Drawing.Color.Green; + + if (lbFormatValue.Text == "Error" || dataFormat != 1) + { + lbFormatValue.ForeColor = System.Drawing.Color.Red; + statusOk = false; + } + else lbFormatValue.ForeColor = System.Drawing.Color.Green; + + if (lbChannelCountValue.Text == "Error" || (channelCount > 2 || channelCount < 1)) + { + lbChannelCountValue.ForeColor = System.Drawing.Color.Red; + statusOk = false; + } + else lbChannelCountValue.ForeColor = System.Drawing.Color.Green; + + if (lbLoopCountValue.Text == "Error" || loopCount > 1) + lbLoopCountValue.ForeColor = System.Drawing.Color.Orange; + else lbLoopCountValue.ForeColor = System.Drawing.Color.Green; + + if (lbLoopStartValue.Text == "Error" || lbLoopStartValue.Text == "-") + lbLoopStartValue.ForeColor = System.Drawing.Color.Orange; + else lbLoopStartValue.ForeColor = System.Drawing.Color.Green; + + if (!statusOk) + { + lbStatusValue.Text = "Not OK!"; + lbStatusValue.ForeColor = System.Drawing.Color.Red; + + btnConvert.Enabled = false; + } + else + { + btnConvert.Enabled = true; + + if (lbLoopCountValue.ForeColor == System.Drawing.Color.Orange || + lbLoopStartValue.ForeColor == System.Drawing.Color.Orange) + { + lbStatusValue.Text = "No Loop!"; + lbStatusValue.ForeColor = System.Drawing.Color.Orange; + + if (rbFromAudioFile.Checked) rbNone.Checked = true; + rbFromAudioFile.Enabled = false; + } + else + { + rbFromAudioFile.Enabled = true; + + lbStatusValue.Text = "OK!"; + lbStatusValue.ForeColor = System.Drawing.Color.Green; + } + } + } + } +} diff --git a/CustomizeMii/CustomizeMii_BnsConvert.resx b/CustomizeMii/CustomizeMii_BnsConvert.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/CustomizeMii/CustomizeMii_BnsConvert.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/CustomizeMii/CustomizeMii_ComplexForwarder.Designer.cs b/CustomizeMii/CustomizeMii_ComplexForwarder.Designer.cs index 56129f0..e81c3b8 100644 --- a/CustomizeMii/CustomizeMii_ComplexForwarder.Designer.cs +++ b/CustomizeMii/CustomizeMii_ComplexForwarder.Designer.cs @@ -47,12 +47,6 @@ namespace CustomizeMii { this.lbAppFolder = new System.Windows.Forms.Label(); this.tbAppFolder = new System.Windows.Forms.TextBox(); - this.panSdUsb = new System.Windows.Forms.Panel(); - this.rbUSB = new System.Windows.Forms.RadioButton(); - this.rbSD = new System.Windows.Forms.RadioButton(); - this.panDolElf = new System.Windows.Forms.Panel(); - this.rbELF = new System.Windows.Forms.RadioButton(); - this.rbDOL = new System.Windows.Forms.RadioButton(); this.cbImage43 = new System.Windows.Forms.CheckBox(); this.cbImage169 = new System.Windows.Forms.CheckBox(); this.tbImage43 = new System.Windows.Forms.TextBox(); @@ -62,14 +56,12 @@ namespace CustomizeMii this.label1 = new System.Windows.Forms.Label(); this.btnOK = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); - this.panSdUsb.SuspendLayout(); - this.panDolElf.SuspendLayout(); this.SuspendLayout(); // // lbAppFolder // this.lbAppFolder.AutoSize = true; - this.lbAppFolder.Location = new System.Drawing.Point(12, 13); + this.lbAppFolder.Location = new System.Drawing.Point(12, 17); this.lbAppFolder.Name = "lbAppFolder"; this.lbAppFolder.Size = new System.Drawing.Size(107, 13); this.lbAppFolder.TabIndex = 0; @@ -77,77 +69,15 @@ namespace CustomizeMii // // tbAppFolder // - this.tbAppFolder.Location = new System.Drawing.Point(125, 10); + this.tbAppFolder.Location = new System.Drawing.Point(125, 14); this.tbAppFolder.Name = "tbAppFolder"; this.tbAppFolder.Size = new System.Drawing.Size(221, 20); this.tbAppFolder.TabIndex = 1; // - // panSdUsb - // - this.panSdUsb.Controls.Add(this.rbUSB); - this.panSdUsb.Controls.Add(this.rbSD); - this.panSdUsb.Location = new System.Drawing.Point(15, 38); - this.panSdUsb.Name = "panSdUsb"; - this.panSdUsb.Size = new System.Drawing.Size(157, 64); - this.panSdUsb.TabIndex = 2; - // - // rbUSB - // - this.rbUSB.AutoSize = true; - this.rbUSB.Location = new System.Drawing.Point(24, 35); - this.rbUSB.Name = "rbUSB"; - this.rbUSB.Size = new System.Drawing.Size(87, 17); - this.rbUSB.TabIndex = 0; - this.rbUSB.TabStop = true; - this.rbUSB.Text = "Try USB First"; - this.rbUSB.UseVisualStyleBackColor = true; - // - // rbSD - // - this.rbSD.AutoSize = true; - this.rbSD.Location = new System.Drawing.Point(24, 12); - this.rbSD.Name = "rbSD"; - this.rbSD.Size = new System.Drawing.Size(80, 17); - this.rbSD.TabIndex = 0; - this.rbSD.TabStop = true; - this.rbSD.Text = "Try SD First"; - this.rbSD.UseVisualStyleBackColor = true; - // - // panDolElf - // - this.panDolElf.Controls.Add(this.rbELF); - this.panDolElf.Controls.Add(this.rbDOL); - this.panDolElf.Location = new System.Drawing.Point(189, 38); - this.panDolElf.Name = "panDolElf"; - this.panDolElf.Size = new System.Drawing.Size(157, 64); - this.panDolElf.TabIndex = 2; - // - // rbELF - // - this.rbELF.AutoSize = true; - this.rbELF.Location = new System.Drawing.Point(41, 35); - this.rbELF.Name = "rbELF"; - this.rbELF.Size = new System.Drawing.Size(84, 17); - this.rbELF.TabIndex = 0; - this.rbELF.TabStop = true; - this.rbELF.Text = "Try ELF First"; - this.rbELF.UseVisualStyleBackColor = true; - // - // rbDOL - // - this.rbDOL.AutoSize = true; - this.rbDOL.Location = new System.Drawing.Point(41, 12); - this.rbDOL.Name = "rbDOL"; - this.rbDOL.Size = new System.Drawing.Size(87, 17); - this.rbDOL.TabIndex = 0; - this.rbDOL.TabStop = true; - this.rbDOL.Text = "Try DOL First"; - this.rbDOL.UseVisualStyleBackColor = true; - // // cbImage43 // this.cbImage43.AutoSize = true; - this.cbImage43.Location = new System.Drawing.Point(15, 141); + this.cbImage43.Location = new System.Drawing.Point(15, 111); this.cbImage43.Name = "cbImage43"; this.cbImage43.Size = new System.Drawing.Size(73, 17); this.cbImage43.TabIndex = 3; @@ -158,7 +88,7 @@ namespace CustomizeMii // cbImage169 // this.cbImage169.AutoSize = true; - this.cbImage169.Location = new System.Drawing.Point(15, 171); + this.cbImage169.Location = new System.Drawing.Point(15, 141); this.cbImage169.Name = "cbImage169"; this.cbImage169.Size = new System.Drawing.Size(79, 17); this.cbImage169.TabIndex = 3; @@ -169,7 +99,7 @@ namespace CustomizeMii // tbImage43 // this.tbImage43.Enabled = false; - this.tbImage43.Location = new System.Drawing.Point(94, 139); + this.tbImage43.Location = new System.Drawing.Point(94, 109); this.tbImage43.Name = "tbImage43"; this.tbImage43.Size = new System.Drawing.Size(171, 20); this.tbImage43.TabIndex = 4; @@ -177,7 +107,7 @@ namespace CustomizeMii // tbImage169 // this.tbImage169.Enabled = false; - this.tbImage169.Location = new System.Drawing.Point(94, 168); + this.tbImage169.Location = new System.Drawing.Point(94, 138); this.tbImage169.Name = "tbImage169"; this.tbImage169.Size = new System.Drawing.Size(171, 20); this.tbImage169.TabIndex = 5; @@ -185,7 +115,7 @@ namespace CustomizeMii // btnBrowseImage43 // this.btnBrowseImage43.Enabled = false; - this.btnBrowseImage43.Location = new System.Drawing.Point(271, 139); + this.btnBrowseImage43.Location = new System.Drawing.Point(271, 109); this.btnBrowseImage43.Name = "btnBrowseImage43"; this.btnBrowseImage43.Size = new System.Drawing.Size(75, 23); this.btnBrowseImage43.TabIndex = 6; @@ -196,7 +126,7 @@ namespace CustomizeMii // btnBrowseImage169 // this.btnBrowseImage169.Enabled = false; - this.btnBrowseImage169.Location = new System.Drawing.Point(271, 168); + this.btnBrowseImage169.Location = new System.Drawing.Point(271, 138); this.btnBrowseImage169.Name = "btnBrowseImage169"; this.btnBrowseImage169.Size = new System.Drawing.Size(75, 23); this.btnBrowseImage169.TabIndex = 6; @@ -206,16 +136,17 @@ namespace CustomizeMii // // label1 // - this.label1.Location = new System.Drawing.Point(0, 116); + this.label1.Location = new System.Drawing.Point(0, 55); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(358, 13); + this.label1.Size = new System.Drawing.Size(358, 40); this.label1.TabIndex = 7; - this.label1.Text = "The images must be 640 x 480, else they will be resized!"; + this.label1.Text = "The images must be 640 x 480, else they will be resized!\r\nThe 16:9 image should b" + + "e made in 832 x 480 and resized\r\nto 640 x 480, it will be streched on the Wii!"; this.label1.TextAlign = System.Drawing.ContentAlignment.TopCenter; // // btnOK // - this.btnOK.Location = new System.Drawing.Point(15, 209); + this.btnOK.Location = new System.Drawing.Point(15, 179); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(160, 23); this.btnOK.TabIndex = 8; @@ -225,7 +156,7 @@ namespace CustomizeMii // // btnCancel // - this.btnCancel.Location = new System.Drawing.Point(186, 209); + this.btnCancel.Location = new System.Drawing.Point(186, 179); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(160, 23); this.btnCancel.TabIndex = 8; @@ -237,7 +168,7 @@ namespace CustomizeMii // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(358, 245); + this.ClientSize = new System.Drawing.Size(358, 220); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOK); this.Controls.Add(this.label1); @@ -247,17 +178,11 @@ namespace CustomizeMii this.Controls.Add(this.tbImage43); this.Controls.Add(this.cbImage169); this.Controls.Add(this.cbImage43); - this.Controls.Add(this.panDolElf); - this.Controls.Add(this.panSdUsb); this.Controls.Add(this.tbAppFolder); this.Controls.Add(this.lbAppFolder); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Name = "CustomizeMii_ComplexForwarder"; this.Text = "CustomizeMii_ComplexForwarder"; - this.panSdUsb.ResumeLayout(false); - this.panSdUsb.PerformLayout(); - this.panDolElf.ResumeLayout(false); - this.panDolElf.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -266,14 +191,8 @@ namespace CustomizeMii #endregion private System.Windows.Forms.Label lbAppFolder; - private System.Windows.Forms.Panel panSdUsb; - private System.Windows.Forms.Panel panDolElf; private System.Windows.Forms.Label label1; public System.Windows.Forms.TextBox tbAppFolder; - public System.Windows.Forms.RadioButton rbUSB; - public System.Windows.Forms.RadioButton rbSD; - public System.Windows.Forms.RadioButton rbELF; - public System.Windows.Forms.RadioButton rbDOL; public System.Windows.Forms.CheckBox cbImage43; public System.Windows.Forms.CheckBox cbImage169; public System.Windows.Forms.TextBox tbImage43; diff --git a/CustomizeMii/CustomizeMii_Main.Designer.cs b/CustomizeMii/CustomizeMii_Main.Designer.cs index 9a7cdbb..409cea5 100644 --- a/CustomizeMii/CustomizeMii_Main.Designer.cs +++ b/CustomizeMii/CustomizeMii_Main.Designer.cs @@ -80,6 +80,7 @@ namespace CustomizeMii this.tbAllLanguages = new System.Windows.Forms.TextBox(); this.lbAllLanguages = new System.Windows.Forms.Label(); this.tabOptions = new System.Windows.Forms.TabPage(); + this.btnOptionsExtract = new System.Windows.Forms.Button(); this.btnForwarder = new System.Windows.Forms.Button(); this.cbFailureChecks = new System.Windows.Forms.CheckBox(); this.cbLz77 = new System.Windows.Forms.CheckBox(); @@ -150,6 +151,22 @@ namespace CustomizeMii this.cmForwarder = new System.Windows.Forms.ContextMenuStrip(this.components); this.cmSimpleForwarder = new System.Windows.Forms.ToolStripMenuItem(); this.cmComplexForwarder = new System.Windows.Forms.ToolStripMenuItem(); + this.cmOptionsExtract = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmExtractWad = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractDol = new System.Windows.Forms.ToolStripMenuItem(); + this.tsExtractSound = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractSoundAsBin = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractSoundAsAudio = new System.Windows.Forms.ToolStripMenuItem(); + this.tsExtractImages = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractBannerImages = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractIconImages = new System.Windows.Forms.ToolStripMenuItem(); + this.cmExtractBothImages = new System.Windows.Forms.ToolStripMenuItem(); + this.cmSound = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmLoadAudioFile = new System.Windows.Forms.ToolStripMenuItem(); + this.cmConvertToBns = new System.Windows.Forms.ToolStripMenuItem(); + this.cmDol = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmLoadDol = new System.Windows.Forms.ToolStripMenuItem(); + this.cmDolFromSource = new System.Windows.Forms.ToolStripMenuItem(); this.tabControl.SuspendLayout(); this.tabSource.SuspendLayout(); this.tabTitle.SuspendLayout(); @@ -162,6 +179,9 @@ namespace CustomizeMii this.tabCredits.SuspendLayout(); this.ssMain.SuspendLayout(); this.cmForwarder.SuspendLayout(); + this.cmOptionsExtract.SuspendLayout(); + this.cmSound.SuspendLayout(); + this.cmDol.SuspendLayout(); this.SuspendLayout(); // // btnCreateWad @@ -314,7 +334,7 @@ namespace CustomizeMii // // btnBrowseSource // - this.btnBrowseSource.Location = new System.Drawing.Point(360, 12); + this.btnBrowseSource.Location = new System.Drawing.Point(360, 13); this.btnBrowseSource.Name = "btnBrowseSource"; this.btnBrowseSource.Size = new System.Drawing.Size(75, 23); this.btnBrowseSource.TabIndex = 2; @@ -514,6 +534,7 @@ namespace CustomizeMii // // tabOptions // + this.tabOptions.Controls.Add(this.btnOptionsExtract); this.tabOptions.Controls.Add(this.btnForwarder); this.tabOptions.Controls.Add(this.cbFailureChecks); this.tabOptions.Controls.Add(this.cbLz77); @@ -536,6 +557,16 @@ namespace CustomizeMii this.tabOptions.Text = "Options"; this.tabOptions.UseVisualStyleBackColor = true; // + // btnOptionsExtract + // + this.btnOptionsExtract.Location = new System.Drawing.Point(360, 47); + this.btnOptionsExtract.Name = "btnOptionsExtract"; + this.btnOptionsExtract.Size = new System.Drawing.Size(75, 23); + this.btnOptionsExtract.TabIndex = 14; + this.btnOptionsExtract.Text = "Extract..."; + this.btnOptionsExtract.UseVisualStyleBackColor = true; + this.btnOptionsExtract.Click += new System.EventHandler(this.btnOptionsExtract_Click); + // // btnForwarder // this.btnForwarder.Location = new System.Drawing.Point(360, 109); @@ -553,12 +584,15 @@ namespace CustomizeMii this.cbFailureChecks.Name = "cbFailureChecks"; this.cbFailureChecks.Size = new System.Drawing.Size(172, 17); this.cbFailureChecks.TabIndex = 12; + this.cbFailureChecks.Tag = "Independent"; this.cbFailureChecks.Text = "/!\\ Turn off security checks /!\\"; this.cbFailureChecks.UseVisualStyleBackColor = true; // // cbLz77 // this.cbLz77.AutoSize = true; + this.cbLz77.Checked = true; + this.cbLz77.CheckState = System.Windows.Forms.CheckState.Checked; this.cbLz77.Location = new System.Drawing.Point(11, 180); this.cbLz77.Name = "cbLz77"; this.cbLz77.Size = new System.Drawing.Size(134, 17); @@ -578,7 +612,7 @@ namespace CustomizeMii // // btnBrowseSound // - this.btnBrowseSound.Location = new System.Drawing.Point(360, 144); + this.btnBrowseSound.Location = new System.Drawing.Point(360, 145); this.btnBrowseSound.Name = "btnBrowseSound"; this.btnBrowseSound.Size = new System.Drawing.Size(75, 23); this.btnBrowseSound.TabIndex = 9; @@ -609,7 +643,7 @@ namespace CustomizeMii // // btnBrowseDol // - this.btnBrowseDol.Location = new System.Drawing.Point(360, 80); + this.btnBrowseDol.Location = new System.Drawing.Point(360, 81); this.btnBrowseDol.Name = "btnBrowseDol"; this.btnBrowseDol.Size = new System.Drawing.Size(75, 23); this.btnBrowseDol.TabIndex = 6; @@ -1257,7 +1291,7 @@ namespace CustomizeMii this.cmSimpleForwarder, this.cmComplexForwarder}); this.cmForwarder.Name = "contextMenuStrip1"; - this.cmForwarder.Size = new System.Drawing.Size(178, 70); + this.cmForwarder.Size = new System.Drawing.Size(178, 48); // // cmSimpleForwarder // @@ -1273,6 +1307,128 @@ namespace CustomizeMii this.cmComplexForwarder.Text = "Complex Forwarder"; this.cmComplexForwarder.Click += new System.EventHandler(this.cmForwarderItem_Click); // + // cmOptionsExtract + // + this.cmOptionsExtract.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmExtractWad, + this.cmExtractDol, + this.tsExtractSound, + this.tsExtractImages}); + this.cmOptionsExtract.Name = "cmOptionsExtract"; + this.cmOptionsExtract.Size = new System.Drawing.Size(153, 92); + // + // cmExtractWad + // + this.cmExtractWad.Name = "cmExtractWad"; + this.cmExtractWad.Size = new System.Drawing.Size(152, 22); + this.cmExtractWad.Text = "WAD Contents"; + this.cmExtractWad.Click += new System.EventHandler(this.cmExtractWad_Click); + // + // cmExtractDol + // + this.cmExtractDol.Name = "cmExtractDol"; + this.cmExtractDol.Size = new System.Drawing.Size(152, 22); + this.cmExtractDol.Text = "DOL"; + this.cmExtractDol.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // tsExtractSound + // + this.tsExtractSound.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmExtractSoundAsBin, + this.cmExtractSoundAsAudio}); + this.tsExtractSound.Name = "tsExtractSound"; + this.tsExtractSound.Size = new System.Drawing.Size(152, 22); + this.tsExtractSound.Text = "Sound"; + // + // cmExtractSoundAsBin + // + this.cmExtractSoundAsBin.Name = "cmExtractSoundAsBin"; + this.cmExtractSoundAsBin.Size = new System.Drawing.Size(143, 22); + this.cmExtractSoundAsBin.Text = "As sound.bin"; + this.cmExtractSoundAsBin.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // cmExtractSoundAsAudio + // + this.cmExtractSoundAsAudio.Name = "cmExtractSoundAsAudio"; + this.cmExtractSoundAsAudio.Size = new System.Drawing.Size(143, 22); + this.cmExtractSoundAsAudio.Text = "As Audiofile"; + this.cmExtractSoundAsAudio.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // tsExtractImages + // + this.tsExtractImages.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmExtractBannerImages, + this.cmExtractIconImages, + this.cmExtractBothImages}); + this.tsExtractImages.Name = "tsExtractImages"; + this.tsExtractImages.Size = new System.Drawing.Size(152, 22); + this.tsExtractImages.Text = "Images"; + // + // cmExtractBannerImages + // + this.cmExtractBannerImages.Name = "cmExtractBannerImages"; + this.cmExtractBannerImages.Size = new System.Drawing.Size(111, 22); + this.cmExtractBannerImages.Text = "Banner"; + this.cmExtractBannerImages.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // cmExtractIconImages + // + this.cmExtractIconImages.Name = "cmExtractIconImages"; + this.cmExtractIconImages.Size = new System.Drawing.Size(111, 22); + this.cmExtractIconImages.Text = "Icon"; + this.cmExtractIconImages.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // cmExtractBothImages + // + this.cmExtractBothImages.Name = "cmExtractBothImages"; + this.cmExtractBothImages.Size = new System.Drawing.Size(111, 22); + this.cmExtractBothImages.Text = "Both"; + this.cmExtractBothImages.Click += new System.EventHandler(this.cmOptionsExtract_MouseClick); + // + // cmSound + // + this.cmSound.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmLoadAudioFile, + this.cmConvertToBns}); + this.cmSound.Name = "cmSound"; + this.cmSound.Size = new System.Drawing.Size(159, 48); + // + // cmLoadAudioFile + // + this.cmLoadAudioFile.Name = "cmLoadAudioFile"; + this.cmLoadAudioFile.Size = new System.Drawing.Size(158, 22); + this.cmLoadAudioFile.Text = "Load Audio File"; + this.cmLoadAudioFile.Click += new System.EventHandler(this.cmLoadAudioFile_Click); + // + // cmConvertToBns + // + this.cmConvertToBns.Name = "cmConvertToBns"; + this.cmConvertToBns.Size = new System.Drawing.Size(158, 22); + this.cmConvertToBns.Text = "Convert To BNS"; + this.cmConvertToBns.Click += new System.EventHandler(this.cmConvertToBns_Click); + // + // cmDol + // + this.cmDol.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmLoadDol, + this.cmDolFromSource}); + this.cmDol.Name = "cmDol"; + this.cmDol.Size = new System.Drawing.Size(200, 48); + // + // cmLoadDol + // + this.cmLoadDol.Name = "cmLoadDol"; + this.cmLoadDol.Size = new System.Drawing.Size(199, 22); + this.cmLoadDol.Text = "Load DOL File"; + this.cmLoadDol.Click += new System.EventHandler(this.cmLoadDol_Click); + // + // cmDolFromSource + // + this.cmDolFromSource.Name = "cmDolFromSource"; + this.cmDolFromSource.Size = new System.Drawing.Size(199, 22); + this.cmDolFromSource.Text = "Take From Source WAD"; + this.cmDolFromSource.Click += new System.EventHandler(this.cmDolFromSource_Click); + // // CustomizeMii_Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1308,6 +1464,9 @@ namespace CustomizeMii this.ssMain.ResumeLayout(false); this.ssMain.PerformLayout(); this.cmForwarder.ResumeLayout(false); + this.cmOptionsExtract.ResumeLayout(false); + this.cmSound.ResumeLayout(false); + this.cmDol.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -1418,6 +1577,23 @@ namespace CustomizeMii private System.Windows.Forms.ContextMenuStrip cmForwarder; private System.Windows.Forms.ToolStripMenuItem cmSimpleForwarder; private System.Windows.Forms.ToolStripMenuItem cmComplexForwarder; + private System.Windows.Forms.Button btnOptionsExtract; + private System.Windows.Forms.ContextMenuStrip cmOptionsExtract; + private System.Windows.Forms.ToolStripMenuItem cmExtractDol; + private System.Windows.Forms.ToolStripMenuItem tsExtractSound; + private System.Windows.Forms.ToolStripMenuItem tsExtractImages; + private System.Windows.Forms.ToolStripMenuItem cmExtractBannerImages; + private System.Windows.Forms.ToolStripMenuItem cmExtractIconImages; + private System.Windows.Forms.ToolStripMenuItem cmExtractBothImages; + private System.Windows.Forms.ToolStripMenuItem cmExtractSoundAsBin; + private System.Windows.Forms.ToolStripMenuItem cmExtractSoundAsAudio; + private System.Windows.Forms.ContextMenuStrip cmSound; + private System.Windows.Forms.ToolStripMenuItem cmLoadAudioFile; + private System.Windows.Forms.ToolStripMenuItem cmConvertToBns; + private System.Windows.Forms.ToolStripMenuItem cmExtractWad; + private System.Windows.Forms.ContextMenuStrip cmDol; + private System.Windows.Forms.ToolStripMenuItem cmLoadDol; + private System.Windows.Forms.ToolStripMenuItem cmDolFromSource; } } diff --git a/CustomizeMii/CustomizeMii_Main.cs b/CustomizeMii/CustomizeMii_Main.cs index 6c91d16..d7421e1 100644 --- a/CustomizeMii/CustomizeMii_Main.cs +++ b/CustomizeMii/CustomizeMii_Main.cs @@ -15,6 +15,9 @@ * along with this program. If not, see . */ +//#define Mono //Change all '\\' to '/' (in all files) while compiling for OS X / Linux (Mono) +//#define Debug //Always remember to turn off :) + using System; using System.Collections.Generic; using System.ComponentModel; @@ -24,32 +27,38 @@ using System.IO; using System.Net; using System.Text.RegularExpressions; using System.Windows.Forms; + +#if !Mono using ForwardMii; +#endif namespace CustomizeMii { public partial class CustomizeMii_Main : Form { - const string version = "1.2"; //Hint for myself: Never use a char in the Version (UpdateCheck)! + const string version = "2.0"; //Hint for myself: Never use a char in the Version (UpdateCheck)! const int SoundMaxLength = 30; //In seconds const int SoundWarningLength = 20; //In seconds - protected string TempPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\"; - protected string TempWadPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\TempWad.wad"; - protected string TempUnpackPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\"; - protected string TempBannerPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Banner\\"; - protected string TempIconPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Icon\\"; - protected string TempSoundPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\sound.bin"; - protected string TempWavePath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp.wav"; - protected string TempTempPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp\\"; - protected string TempUnpackBannerTplPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\timg\\"; - protected string TempUnpackIconTplPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\timg\\"; - protected string TempUnpackBannerBrlytPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\blyt\\"; - protected string TempUnpackIconBrlytPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\blyt\\"; - protected string TempUnpackBannerBrlanPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\anim\\"; - protected string TempUnpackIconBrlanPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\anim\\"; - protected string[] ButtonTexts = new string[] { "Create WAD!", "Fire!", "Go Go Go!", "Let's do it!", "What are you waitin' for?", "I want my Channel!", "Houston, We've Got a Problem!", "Error, please contact anyone!", "Isn't she sweet?", "Is that milk?", "In your face!", "_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_", "Wo ist der Notausgang?", "Take me to a higher place!", "What's goin' on?", "I'm a Button!", "Click!", "Today's date is " + DateTime.Now.ToShortDateString(), "Launch Time: " + DateTime.Now.ToLongTimeString() }; - protected string[] SourceWadUrls = new string[] { "http://wadder.net/bases/StaticBase.wad", "http://wadder.net/bases/GenesisGX.wad", "http://wadder.net/bases/MP-CE-Std.wad", "http://wadder.net/bases/MP-CE-Ext.wad", "http://wadder.net/bases/SNES9XGX.wad", "http://wadder.net/bases/FCEUGX-wilsoff.wad", "http://wadder.net/bases/FCEUGX.wad", "http://wadder.net/bases/Wii64.wad", "http://wadder.net/bases/WiiSXFull.wad", "http://wadder.net/bases/WiiSXRetro.wad", "http://wadder.net/bases/WADderBase1.wad", "http://wadder.net/bases/WADderBase2.wad", "http://wadder.net/bases/WADderBase3.wad", "http://wadder.net/bases/UniiLoader.wad", "http://wadder.net/bases/BackupChannel.wad" }; - protected string[] SourceWadPreviewUrls = new string[] { "http://www.youtube.com/watch?v=pFNKldTYQq0", "http://www.youtube.com/watch?v=p9A6iEQvv9w", "http://www.youtube.com/watch?v=Up1RZebUc_U", "http://www.youtube.com/watch?v=Up1RZebUc_U", "http://www.youtube.com/watch?v=P-Mxd6DMvFY", "http://www.youtube.com/watch?v=wrbrg-DH_h4", "http://www.youtube.com/watch?v=MfiVbQaiXw8", "http://www.youtube.com/watch?v=krCQ2J7ZH8Y", "http://www.youtube.com/watch?v=rZC1DKUM6QI", "http://www.youtube.com/watch?v=Uiy8w-bp1kI", "http://www.youtube.com/watch?v=BbSYCSI8tz8", "http://www.youtube.com/watch?v=PIFZevHQ8lQ", "http://www.youtube.com/watch?v=OIhvDNjphhc", "http://www.youtube.com/watch?v=KLcncEArQLY&NR=1", "http://www.youtube.com/watch?v=xE_EgdCRV1I" }; + const int BnsWarningLength = 45; //In seconds + public static string TempPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\"; + public static string TempWadPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\TempWad.wad"; + public static string TempUnpackPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\"; + public static string TempBannerPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Banner\\"; + public static string TempIconPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Icon\\"; + public static string TempSoundPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\sound.bin"; + public static string TempWavePath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp.wav"; + public static string TempBnsPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp.bns"; + public static string TempDolPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp.dol"; + public static string TempTempPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Temp\\"; + public static string TempUnpackBannerTplPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\timg\\"; + public static string TempUnpackIconTplPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\timg\\"; + public static string TempUnpackBannerBrlytPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\blyt\\"; + public static string TempUnpackIconBrlytPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\blyt\\"; + public static string TempUnpackBannerBrlanPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\banner.bin_OUT\\arc\\anim\\"; + public static string TempUnpackIconBrlanPath = Path.GetTempPath() + "CustomizeMii_Temp\\XXX\\Unpack\\00000000.app_OUT\\meta\\icon.bin_OUT\\arc\\anim\\"; + public static string[] ButtonTexts = new string[] { "Image", "Create WAD!", "Fire!", "Go Go Go!", "Let's do it!", "What are you waitin' for?", "I want my Channel!", "Houston, We've Got a Problem!", "Error, please contact anyone!", "Isn't she sweet?", "Is that milk?", "In your face!", "_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_", "Take me to a higher place!", "What's goin' on?", "I'm a Button!", "Click!", "Today's date is " + DateTime.Now.ToShortDateString(), "Launch Time: " + DateTime.Now.ToLongTimeString(), string.Format("My name is {0}", Environment.UserName) }; + public static string[] SourceWadUrls = new string[] { "http://wadder.net/bases/StaticBase.wad", "http://wadder.net/bases/GenesisGX.wad", "http://wadder.net/bases/MP-CE-Std.wad", "http://wadder.net/bases/MP-CE-Ext.wad", "http://wadder.net/bases/SNES9XGX.wad", "http://wadder.net/bases/FCEUGX-wilsoff.wad", "http://wadder.net/bases/FCEUGX.wad", "http://wadder.net/bases/Wii64.wad", "http://wadder.net/bases/WiiSXFull.wad", "http://wadder.net/bases/WiiSXRetro.wad", "http://wadder.net/bases/WADderBase1.wad", "http://wadder.net/bases/WADderBase2.wad", "http://wadder.net/bases/WADderBase3.wad", "http://wadder.net/bases/UniiLoader.wad", "http://wadder.net/bases/BackupChannel.wad" }; + public static string[] SourceWadPreviewUrls = new string[] { "http://www.youtube.com/watch?v=pFNKldTYQq0", "http://www.youtube.com/watch?v=p9A6iEQvv9w", "http://www.youtube.com/watch?v=Up1RZebUc_U", "http://www.youtube.com/watch?v=Up1RZebUc_U", "http://www.youtube.com/watch?v=P-Mxd6DMvFY", "http://www.youtube.com/watch?v=wrbrg-DH_h4", "http://www.youtube.com/watch?v=MfiVbQaiXw8", "http://www.youtube.com/watch?v=krCQ2J7ZH8Y", "http://www.youtube.com/watch?v=rZC1DKUM6QI", "http://www.youtube.com/watch?v=Uiy8w-bp1kI", "http://www.youtube.com/watch?v=BbSYCSI8tz8", "http://www.youtube.com/watch?v=PIFZevHQ8lQ", "http://www.youtube.com/watch?v=OIhvDNjphhc", "http://www.youtube.com/watch?v=KLcncEArQLY&NR=1", "http://www.youtube.com/watch?v=xE_EgdCRV1I" }; private string BannerTplPath = string.Empty; private string IconTplPath = string.Empty; private string SourceWad = string.Empty; @@ -60,21 +69,19 @@ namespace CustomizeMii private string BannerReplace = string.Empty; private string IconReplace = string.Empty; private string SoundReplace = string.Empty; - private int NandLoader = 0; - private TextBox tbToChange; - private string textToChange; private bool BrlytChanged = false; private bool BrlanChanged = false; - private int ProgressValue; - private string ProgressState; + private Progress currentProgress; private EventHandler ProgressUpdate; - private ToolTip TTip = new ToolTip(); private int UnpackFolderErrorCount = 0; private Stopwatch CreationTimer = new Stopwatch(); - private List Transparents = new List(); + private List BannerTransparents = new List(); + private List IconTransparents = new List(); private string Mp3Path; private Forwarder.Simple SimpleForwarder = new Forwarder.Simple(); private Forwarder.Complex ComplexForwarder = new Forwarder.Complex(); + private delegate void BoxInvoker(string message); + private delegate void SetTextInvoker(string text, TextBox tb); public CustomizeMii_Main() { @@ -86,14 +93,27 @@ namespace CustomizeMii { UpdatePaths(); UpdateCheck(); + +#if !Mono UpdateCheckForwardMii(); - InitializeStartup(); CommonKeyCheck(); +#endif + + InitializeStartup(); + +#if Mono + //TextBox.MaxLength is not implemented in Mono, so don't use it + for (int i = 0; i < tabControl.TabPages.Count; i++) + for(int j=0;j 0) + { + BackgroundWorker bwLoadChannel = new BackgroundWorker(); + bwLoadChannel.DoWork += new DoWorkEventHandler(bwLoadChannel_DoWork); + bwLoadChannel.ProgressChanged += new ProgressChangedEventHandler(bwLoadChannel_ProgressChanged); + bwLoadChannel.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoadChannel_RunWorkerCompleted); + bwLoadChannel.WorkerReportsProgress = true; + bwLoadChannel.RunWorkerAsync(TempWadPath); + } + else + { + SetText(tbSourceWad, string.Empty); + File.Delete(TempWadPath); + ErrorBox("The requested file couldn't be downloaded."); + } + } } private void btnPreviewBaseWad_Click(object sender, EventArgs e) @@ -1131,19 +1061,27 @@ namespace CustomizeMii if (sfd.ShowDialog() == DialogResult.OK) { - try + if (tbSourceWad.Text == SourceWadUrls[lbxBaseWads.SelectedIndex] && File.Exists(TempWadPath)) { - WebClient SaveClient = new WebClient(); - SaveClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(SaveClient_DownloadProgressChanged); - SaveClient.DownloadFileCompleted += new AsyncCompletedEventHandler(SaveClient_DownloadFileCompleted); - - lbStatusText.Text = "Downloading Base WAD..."; - pbProgress.Value = 0; - SaveClient.DownloadFileAsync(new Uri(Url), sfd.FileName); + File.Copy(TempWadPath, sfd.FileName, true); + InfoBox(string.Format("Saved channel as {0}", Path.GetFileName(sfd.FileName))); } - catch (Exception ex) + else { - ErrorBox(ex.Message); + try + { + WebClient SaveClient = new WebClient(); + SaveClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(SaveClient_DownloadProgressChanged); + SaveClient.DownloadFileCompleted += new AsyncCompletedEventHandler(SaveClient_DownloadFileCompleted); + + lbStatusText.Text = "Downloading Base WAD..."; + pbProgress.Value = 0; + SaveClient.DownloadFileAsync(new Uri(Url), sfd.FileName); + } + catch (Exception ex) + { + ErrorBox(ex.Message); + } } } } @@ -1185,7 +1123,8 @@ namespace CustomizeMii private void btnBrowseReplace_Click(object sender, EventArgs e) { - if (!string.IsNullOrEmpty(tbSourceWad.Text)){ + if (!string.IsNullOrEmpty(tbSourceWad.Text)) + { if (pbProgress.Value == 100) { if (cmbReplace.SelectedIndex == 2) //sound @@ -1198,14 +1137,17 @@ namespace CustomizeMii if (ofd.ShowDialog() == DialogResult.OK) { - SoundReplace = ofd.FileName; - SetText(tbReplace, SoundReplace); - BackgroundWorker bwSoundReplace = new BackgroundWorker(); - bwSoundReplace.DoWork += new DoWorkEventHandler(bwSoundReplace_DoWork); - bwSoundReplace.ProgressChanged += new ProgressChangedEventHandler(bwSoundReplace_ProgressChanged); - bwSoundReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSoundReplace_RunWorkerCompleted); - bwSoundReplace.WorkerReportsProgress = true; - bwSoundReplace.RunWorkerAsync(ofd.FileName); + if (ofd.FileName != tbSourceWad.Text) + { + SoundReplace = ofd.FileName; + SetText(tbReplace, SoundReplace); + BackgroundWorker bwSoundReplace = new BackgroundWorker(); + bwSoundReplace.DoWork += new DoWorkEventHandler(bwSoundReplace_DoWork); + bwSoundReplace.ProgressChanged += new ProgressChangedEventHandler(bwSoundReplace_ProgressChanged); + bwSoundReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSoundReplace_RunWorkerCompleted); + bwSoundReplace.WorkerReportsProgress = true; + bwSoundReplace.RunWorkerAsync(ofd.FileName); + } } } catch (Exception ex) @@ -1225,14 +1167,17 @@ namespace CustomizeMii if (ofd.ShowDialog() == DialogResult.OK) { - IconReplace = ofd.FileName; - SetText(tbReplace, IconReplace); - BackgroundWorker bwIconReplace = new BackgroundWorker(); - bwIconReplace.DoWork += new DoWorkEventHandler(bwIconReplace_DoWork); - bwIconReplace.ProgressChanged += new ProgressChangedEventHandler(bwIconReplace_ProgressChanged); - bwIconReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwIconReplace_RunWorkerCompleted); - bwIconReplace.WorkerReportsProgress = true; - bwIconReplace.RunWorkerAsync(ofd.FileName); + if (ofd.FileName != tbSourceWad.Text) + { + IconReplace = ofd.FileName; + SetText(tbReplace, IconReplace); + BackgroundWorker bwIconReplace = new BackgroundWorker(); + bwIconReplace.DoWork += new DoWorkEventHandler(bwIconReplace_DoWork); + bwIconReplace.ProgressChanged += new ProgressChangedEventHandler(bwIconReplace_ProgressChanged); + bwIconReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwIconReplace_RunWorkerCompleted); + bwIconReplace.WorkerReportsProgress = true; + bwIconReplace.RunWorkerAsync(ofd.FileName); + } } } catch (Exception ex) @@ -1252,14 +1197,17 @@ namespace CustomizeMii if (ofd.ShowDialog() == DialogResult.OK) { - BannerReplace = ofd.FileName; - SetText(tbReplace, BannerReplace); - BackgroundWorker bwBannerReplace = new BackgroundWorker(); - bwBannerReplace.DoWork += new DoWorkEventHandler(bwBannerReplace_DoWork); - bwBannerReplace.ProgressChanged += new ProgressChangedEventHandler(bwBannerReplace_ProgressChanged); - bwBannerReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwBannerReplace_RunWorkerCompleted); - bwBannerReplace.WorkerReportsProgress = true; - bwBannerReplace.RunWorkerAsync(ofd.FileName); + if (ofd.FileName != tbSourceWad.Text) + { + BannerReplace = ofd.FileName; + SetText(tbReplace, BannerReplace); + BackgroundWorker bwBannerReplace = new BackgroundWorker(); + bwBannerReplace.DoWork += new DoWorkEventHandler(bwBannerReplace_DoWork); + bwBannerReplace.ProgressChanged += new ProgressChangedEventHandler(bwBannerReplace_ProgressChanged); + bwBannerReplace.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwBannerReplace_RunWorkerCompleted); + bwBannerReplace.WorkerReportsProgress = true; + bwBannerReplace.RunWorkerAsync(ofd.FileName); + } } } catch (Exception ex) @@ -1273,203 +1221,6 @@ namespace CustomizeMii } } - void bwBannerReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - pbProgress.Value = 100; - lbStatusText.Text = string.Empty; - SetText(tbReplace, BannerReplace); - } - - void bwBannerReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) - { - ProgressValue = e.ProgressPercentage; - ProgressState = (string)e.UserState; - - this.Invoke(ProgressUpdate); - } - - void bwBannerReplace_DoWork(object sender, DoWorkEventArgs e) - { - try - { - BackgroundWorker bwBannerReplace = sender as BackgroundWorker; - string thisFile = (string)e.Argument; - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - if (Directory.Exists(TempBannerPath)) Directory.Delete(TempBannerPath, true); - - if (thisFile.EndsWith(".bin")) - { - bwBannerReplace.ReportProgress(0, "Loading banner.bin..."); - Wii.U8.UnpackU8(thisFile, TempBannerPath); - } - else if (thisFile.EndsWith(".app")) - { - bwBannerReplace.ReportProgress(0, "Loading 00000000.app..."); - Wii.U8.UnpackU8(thisFile, TempTempPath); - bwBannerReplace.ReportProgress(50, "Loading banner.bin..."); - Wii.U8.UnpackU8(TempTempPath + "meta\\banner.bin", TempBannerPath); - Directory.Delete(TempTempPath, true); - } - else - { - bwBannerReplace.ReportProgress(0, "Loading WAD..."); - Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); - if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) - throw new Exception("CustomizeMii only handles Channel WADs!"); - bwBannerReplace.ReportProgress(30, "Loading 00000000.app..."); - Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); - bwBannerReplace.ReportProgress(60, "Loading banner.bin..."); - Wii.U8.UnpackU8(TempTempPath + "00000000.app_OUT\\meta\\banner.bin", TempBannerPath); - Directory.Delete(TempTempPath, true); - } - - EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); - EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); - EventHandler AddBrlyts = new EventHandler(this.AddBrlyts); - EventHandler AddBrlans = new EventHandler(this.AddBrlans); - this.Invoke(AddBannerTpls); - this.Invoke(AddIconTpls); - this.Invoke(AddBrlyts); - this.Invoke(AddBrlans); - } - catch (Exception ex) - { - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - if (Directory.Exists(TempBannerPath)) Directory.Delete(TempBannerPath, true); - BannerReplace = string.Empty; - ErrorBox(ex.Message); - } - } - - void bwIconReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - pbProgress.Value = 100; - lbStatusText.Text = string.Empty; - SetText(tbReplace, IconReplace); - } - - void bwIconReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) - { - ProgressValue = e.ProgressPercentage; - ProgressState = (string)e.UserState; - - this.Invoke(ProgressUpdate); - } - - void bwIconReplace_DoWork(object sender, DoWorkEventArgs e) - { - try - { - BackgroundWorker bwIconReplace = sender as BackgroundWorker; - string thisFile = (string)e.Argument; - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - if (Directory.Exists(TempIconPath)) Directory.Delete(TempIconPath, true); - - if (thisFile.EndsWith(".bin")) - { - bwIconReplace.ReportProgress(0, "Loading icon.bin..."); - Wii.U8.UnpackU8(thisFile, TempIconPath); - } - else if (thisFile.EndsWith(".app")) - { - bwIconReplace.ReportProgress(0, "Loading 00000000.app..."); - Wii.U8.UnpackU8(thisFile, TempTempPath); - bwIconReplace.ReportProgress(50, "Loading icon.bin..."); - Wii.U8.UnpackU8(TempTempPath + "meta\\icon.bin", TempIconPath); - Directory.Delete(TempTempPath, true); - } - else - { - bwIconReplace.ReportProgress(0, "Loading WAD..."); - Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); - if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) - throw new Exception("CustomizeMii only handles Channel WADs!"); - bwIconReplace.ReportProgress(30, "Loading 00000000.app..."); - Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); - bwIconReplace.ReportProgress(60, "Loading icon.bin..."); - Wii.U8.UnpackU8(TempTempPath + "00000000.app_OUT\\meta\\icon.bin", TempIconPath); - Directory.Delete(TempTempPath, true); - } - - EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); - EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); - EventHandler AddBrlyts = new EventHandler(this.AddBrlyts); - EventHandler AddBrlans = new EventHandler(this.AddBrlans); - this.Invoke(AddBannerTpls); - this.Invoke(AddIconTpls); - this.Invoke(AddBrlyts); - this.Invoke(AddBrlans); - } - catch (Exception ex) - { - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - if (Directory.Exists(TempIconPath)) Directory.Delete(TempIconPath, true); - IconReplace = string.Empty; - ErrorBox(ex.Message); - } - } - - void bwSoundReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - pbProgress.Value = 100; - lbStatusText.Text = string.Empty; - SetText(tbReplace, SoundReplace); - } - - void bwSoundReplace_ProgressChanged(object sender, ProgressChangedEventArgs e) - { - ProgressValue = e.ProgressPercentage; - ProgressState = (string)e.UserState; - - this.Invoke(ProgressUpdate); - } - - void bwSoundReplace_DoWork(object sender, DoWorkEventArgs e) - { - try - { - BackgroundWorker bwSoundReplace = sender as BackgroundWorker; - string thisFile = (string)e.Argument; - if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - - if (thisFile.EndsWith(".bin")) - { - bwSoundReplace.ReportProgress(0, "Copying sound.bin..."); - File.Copy(thisFile, TempSoundPath); - } - else if (thisFile.EndsWith(".app")) - { - bwSoundReplace.ReportProgress(0, "Loading 00000000.app..."); - Wii.U8.UnpackU8(thisFile, TempTempPath); - bwSoundReplace.ReportProgress(80, "Copying sound.bin..."); - File.Copy(TempTempPath + "meta\\sound.bin", TempSoundPath); - Directory.Delete(TempTempPath, true); - } - else - { - bwSoundReplace.ReportProgress(0, "Loading WAD..."); - Wii.WadUnpack.UnpackWad(thisFile, TempTempPath); - if (Wii.U8.CheckU8(TempTempPath + "00000000.app") == false) - throw new Exception("CustomizeMii only handles Channel WADs!"); - bwSoundReplace.ReportProgress(50, "Loading 00000000.app..."); - Wii.U8.UnpackU8(TempTempPath + "00000000.app", TempTempPath + "00000000.app_OUT"); - bwSoundReplace.ReportProgress(90, "Copying sound.bin..."); - File.Copy(TempTempPath + "00000000.app_OUT\\meta\\sound.bin", TempSoundPath); - Directory.Delete(TempTempPath, true); - } - - SetText(tbSound, SoundReplace); - } - catch (Exception ex) - { - if (Directory.Exists(TempTempPath)) Directory.Delete(TempTempPath, true); - if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); - SoundReplace = string.Empty; - ErrorBox(ex.Message); - } - } - private void btnClearReplace_Click(object sender, EventArgs e) { if (cmbReplace.SelectedIndex == 2) //sound @@ -1497,6 +1248,9 @@ namespace CustomizeMii { if (btnBrowseDol.Text == "Clear") { + if (Directory.Exists(TempTempPath + "TempWad")) Directory.Delete(TempTempPath + "TempWad", true); + if (File.Exists(TempDolPath)) File.Delete(TempDolPath); + SetText(tbDol, string.Empty); btnBrowseDol.Text = "Browse..."; @@ -1505,14 +1259,7 @@ namespace CustomizeMii } else { - OpenFileDialog ofd = new OpenFileDialog(); - ofd.Filter = "DOL Files|*.dol"; - - if (ofd.ShowDialog() == DialogResult.OK) - { - SetText(tbDol, ofd.FileName); - btnBrowseDol.Text = "Clear"; - } + cmDol.Show(MousePosition); } } @@ -1521,45 +1268,12 @@ namespace CustomizeMii if (btnBrowseSound.Text == "Clear") { if (File.Exists(TempWavePath)) File.Delete(TempWavePath); + if (File.Exists(TempBnsPath)) File.Delete(TempBnsPath); SetText(tbSound, string.Empty); btnBrowseSound.Text = "Browse..."; } else - { - if (pbProgress.Value == 100) - { - OpenFileDialog ofd = new OpenFileDialog(); - - if (File.Exists(Application.StartupPath + "\\lame.exe")) - { - ofd.Filter = "Wave Files|*.wav|Mp3 Files|*.mp3|All|*.wav;*.mp3"; - ofd.FilterIndex = 3; - } - else - ofd.Filter = "Wave Files|*.wav"; - - if (ofd.ShowDialog() == DialogResult.OK) - { - if (ofd.FileName.EndsWith(".mp3")) - { - ConvertMp3ToWave(ofd.FileName); - } - else - { - SetText(tbSound, ofd.FileName); - - btnBrowseSound.Text = "Clear"; - - if (!string.IsNullOrEmpty(SoundReplace)) - { - SoundReplace = string.Empty; - if (cmbReplace.SelectedIndex == 2) SetText(tbReplace, SoundReplace); - if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); - } - } - } - } - } + cmSound.Show(MousePosition); } private void lbxBannerTpls_SelectedIndexChanged(object sender, EventArgs e) @@ -1686,7 +1400,7 @@ namespace CustomizeMii byte[] TplArray = Wii.Tools.LoadFileToByteArray(Tpl); Image Img; - if (!ofd.FileName.EndsWith(".tpl")) Img = Image.FromFile(ofd.FileName); + if (!ofd.FileName.ToLower().EndsWith(".tpl")) Img = Image.FromFile(ofd.FileName); else Img = Wii.TPL.ConvertFromTPL(ofd.FileName); int TplFormat; @@ -1740,7 +1454,7 @@ namespace CustomizeMii { try { - if (!sfd.FileName.EndsWith(".tpl")) + if (!sfd.FileName.ToLower().EndsWith(".tpl")) { string Tpl = BannerTplPath + lbxBannerTpls.SelectedItem.ToString().Replace(" (Transparent)", string.Empty); Image Img = Wii.TPL.ConvertFromTPL(Tpl); @@ -1792,7 +1506,7 @@ namespace CustomizeMii else pvw.Height = 250; pvw.pbImage.Image = Img; - pvw.Text = "CustomizeMii - Preview (" + Img.Width.ToString() + " x " + Img.Height.ToString() + ")"; + pvw.Text = string.Format("CustomizeMii - Preview ({0} x {1})", Img.Width, Img.Height); pvw.ShowDialog(); } @@ -1800,6 +1514,8 @@ namespace CustomizeMii { ErrorBox(ex.Message); } + + lbxBannerTpls.Focus(); } } @@ -1823,7 +1539,7 @@ namespace CustomizeMii byte[] TplArray = Wii.Tools.LoadFileToByteArray(Tpl); Image Img; - if (!ofd.FileName.EndsWith(".tpl")) Img = Image.FromFile(ofd.FileName); + if (!ofd.FileName.ToLower().EndsWith(".tpl")) Img = Image.FromFile(ofd.FileName); else Img = Wii.TPL.ConvertFromTPL(ofd.FileName); int TplFormat; @@ -1877,7 +1593,7 @@ namespace CustomizeMii { try { - if (!sfd.FileName.EndsWith(".tpl")) + if (!sfd.FileName.ToLower().EndsWith(".tpl")) { string Tpl = IconTplPath + lbxIconTpls.SelectedItem.ToString().Replace(" (Transparent)", string.Empty); Image Img = Wii.TPL.ConvertFromTPL(Tpl); @@ -1929,14 +1645,16 @@ namespace CustomizeMii else pvw.Height = 250; pvw.pbImage.Image = Img; - pvw.Text = "CustomizeMii - Preview (" + Img.Width.ToString() + " x " + Img.Height.ToString() + ")"; - + pvw.Text = string.Format("CustomizeMii - Preview ({0} x {1})", Img.Width, Img.Height); + pvw.ShowDialog(); } catch (Exception ex) { ErrorBox(ex.Message); } + + lbxIconTpls.Focus(); } } @@ -2043,29 +1761,46 @@ namespace CustomizeMii } //Check Sound length - int soundlength = 0; + int soundLength = 0; if (!string.IsNullOrEmpty(tbSound.Text) && string.IsNullOrEmpty(SoundReplace)) { - string SoundFile = tbSound.Text; - if (tbSound.Text.EndsWith(".mp3")) SoundFile = TempWavePath; - - soundlength = Wii.Sound.GetWaveLength(SoundFile); - if (soundlength > SoundMaxLength) + if (!tbSound.Text.ToLower().EndsWith(".bns") && !tbSound.Text.StartsWith("BNS:")) { - ErrorBox(string.Format("Your Sound is longer than {0} seconds and thus not supported.\nIt is recommended to use a Sound shorter than {1} seconds, the maximum length is {0} seconds!", SoundMaxLength, SoundWarningLength)); - return false; + string SoundFile = tbSound.Text; + if (tbSound.Text.ToLower().EndsWith(".mp3")) SoundFile = TempWavePath; + + soundLength = Wii.Sound.GetWaveLength(SoundFile); + if (soundLength > SoundMaxLength) + { + ErrorBox(string.Format("Your Sound is longer than {0} seconds and thus not supported.\nIt is recommended to use a Sound shorter than {1} seconds, the maximum length is {0} seconds!", SoundMaxLength, SoundWarningLength)); + return false; + } } } /*Errors till here.. From here only Warnings!*/ - if (soundlength > SoundWarningLength) + if (soundLength > SoundWarningLength) { if (MessageBox.Show(string.Format("Your Sound is longer than {0} seconds.\nIt is recommended to use Sounds that are shorter than {0} seconds!\nDo you still want to continue?", SoundWarningLength), "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) return false; } + //Check BNS sound length + if (tbSound.Text.StartsWith("BNS:") || tbSound.Text.EndsWith(".bns")) + { + string bnsFile = tbSound.Text; + if (tbSound.Text.StartsWith("BNS:")) bnsFile = TempBnsPath; + + int bnsLength = Wii.Sound.GetBnsLength(bnsFile); + if (bnsLength > BnsWarningLength) + { + if (MessageBox.Show(string.Format("Your BNS Sound is longer than {0} seconds.\nIt is recommended to use Sounds that are shorter than {0} seconds!\nDo you still want to continue?", BnsWarningLength), "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) + return false; + } + } + //Check if brlyt or brlan were changed if (BrlytChanged == true && BrlanChanged == false) { @@ -2138,10 +1873,10 @@ namespace CustomizeMii foreach (string thisFile in RootFiles) { - if (!thisFile.EndsWith(".app") && - !thisFile.EndsWith(".cert") && - !thisFile.EndsWith(".tik") && - !thisFile.EndsWith(".tmd")) + if (!thisFile.ToLower().EndsWith(".app") && + !thisFile.ToLower().EndsWith(".cert") && + !thisFile.ToLower().EndsWith(".tik") && + !thisFile.ToLower().EndsWith(".tmd")) File.Delete(thisFile); } @@ -2161,7 +1896,7 @@ namespace CustomizeMii foreach (string thisFile in MetaFiles) File.Delete(thisFile); foreach (string thisDir in MetaDirs) - if (!thisDir.EndsWith("meta")) + if (!thisDir.ToLower().EndsWith("meta")) Directory.Delete(thisDir, true); string[] AppFiles = Directory.GetFiles(TempUnpackPath + "00000000.app_OUT\\meta"); @@ -2169,12 +1904,12 @@ namespace CustomizeMii foreach (string thisFile in AppFiles) { - if (!thisFile.EndsWith("banner.bin") && - !thisFile.EndsWith("icon.bin") && - !thisFile.EndsWith("sound.bin")) + if (!thisFile.ToLower().EndsWith("banner.bin") && + !thisFile.ToLower().EndsWith("icon.bin") && + !thisFile.ToLower().EndsWith("sound.bin")) File.Delete(thisFile); } - + if (AppDirs.Length > 2) { foreach (string thisDir in AppDirs) @@ -2184,7 +1919,7 @@ namespace CustomizeMii Directory.Delete(thisDir, true); } } - + //Check banner.bin_OUT / Banner Replace Path if (string.IsNullOrEmpty(BannerReplace)) { @@ -2194,7 +1929,7 @@ namespace CustomizeMii foreach (string thisFile in ArcFiles) File.Delete(thisFile); foreach (string thisDir in ArcDirs) - if (!thisDir.EndsWith("arc")) + if (!thisDir.ToLower().EndsWith("arc")) Directory.Delete(thisDir, true); string[] BannerFiles = Directory.GetFiles(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT\\arc"); @@ -2207,9 +1942,9 @@ namespace CustomizeMii { foreach (string thisDir in BannerDirs) { - if (!thisDir.EndsWith("anim") && - !thisDir.EndsWith("blyt") && - !thisDir.EndsWith("timg")) + if (!thisDir.ToLower().EndsWith("anim") && + !thisDir.ToLower().EndsWith("blyt") && + !thisDir.ToLower().EndsWith("timg")) Directory.Delete(thisDir, true); } } @@ -2219,7 +1954,7 @@ namespace CustomizeMii foreach (string thisFile in AnimFiles) { - if (!thisFile.EndsWith(".brlan")) + if (!thisFile.ToLower().EndsWith(".brlan")) File.Delete(thisFile); } @@ -2231,7 +1966,7 @@ namespace CustomizeMii foreach (string thisFile in BlytFiles) { - if (!thisFile.EndsWith(".brlyt")) + if (!thisFile.ToLower().EndsWith(".brlyt")) File.Delete(thisFile); } @@ -2243,7 +1978,7 @@ namespace CustomizeMii foreach (string thisFile in TimgFiles) { - if (!thisFile.EndsWith(".tpl")) + if (!thisFile.ToLower().EndsWith(".tpl")) File.Delete(thisFile); } @@ -2258,7 +1993,7 @@ namespace CustomizeMii foreach (string thisFile in ArcFiles) File.Delete(thisFile); foreach (string thisDir in ArcDirs) - if (!thisDir.EndsWith("arc")) + if (!thisDir.ToLower().EndsWith("arc")) Directory.Delete(thisDir, true); string[] BannerFiles = Directory.GetFiles(TempBannerPath + "arc"); @@ -2271,9 +2006,9 @@ namespace CustomizeMii { foreach (string thisDir in BannerDirs) { - if (!thisDir.EndsWith("anim") && - !thisDir.EndsWith("blyt") && - !thisDir.EndsWith("timg")) + if (!thisDir.ToLower().EndsWith("anim") && + !thisDir.ToLower().EndsWith("blyt") && + !thisDir.ToLower().EndsWith("timg")) Directory.Delete(thisDir, true); } } @@ -2283,7 +2018,7 @@ namespace CustomizeMii foreach (string thisFile in AnimFiles) { - if (!thisFile.EndsWith(".brlan")) + if (!thisFile.ToLower().EndsWith(".brlan")) File.Delete(thisFile); } @@ -2295,7 +2030,7 @@ namespace CustomizeMii foreach (string thisFile in BlytFiles) { - if (!thisFile.EndsWith(".brlyt")) + if (!thisFile.ToLower().EndsWith(".brlyt")) File.Delete(thisFile); } @@ -2307,7 +2042,7 @@ namespace CustomizeMii foreach (string thisFile in TimgFiles) { - if (!thisFile.EndsWith(".tpl")) + if (!thisFile.ToLower().EndsWith(".tpl")) File.Delete(thisFile); } @@ -2324,7 +2059,7 @@ namespace CustomizeMii foreach (string thisFile in ArcFiles) File.Delete(thisFile); foreach (string thisDir in ArcDirs) - if (!thisDir.EndsWith("arc")) + if (!thisDir.ToLower().EndsWith("arc")) Directory.Delete(thisDir, true); string[] IconFiles = Directory.GetFiles(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT\\arc"); @@ -2337,9 +2072,9 @@ namespace CustomizeMii { foreach (string thisDir in IconDirs) { - if (!thisDir.EndsWith("anim") && - !thisDir.EndsWith("blyt") && - !thisDir.EndsWith("timg")) + if (!thisDir.ToLower().EndsWith("anim") && + !thisDir.ToLower().EndsWith("blyt") && + !thisDir.ToLower().EndsWith("timg")) Directory.Delete(thisDir, true); } } @@ -2349,7 +2084,7 @@ namespace CustomizeMii foreach (string thisFile in AnimFiles) { - if (!thisFile.EndsWith(".brlan")) + if (!thisFile.ToLower().EndsWith(".brlan")) File.Delete(thisFile); } @@ -2361,7 +2096,7 @@ namespace CustomizeMii foreach (string thisFile in BlytFiles) { - if (!thisFile.EndsWith(".brlyt")) + if (!thisFile.ToLower().EndsWith(".brlyt")) File.Delete(thisFile); } @@ -2373,7 +2108,7 @@ namespace CustomizeMii foreach (string thisFile in TimgFiles) { - if (!thisFile.EndsWith(".tpl")) + if (!thisFile.ToLower().EndsWith(".tpl")) File.Delete(thisFile); } @@ -2388,7 +2123,7 @@ namespace CustomizeMii foreach (string thisFile in ArcFiles) File.Delete(thisFile); foreach (string thisDir in ArcDirs) - if (!thisDir.EndsWith("arc")) + if (!thisDir.ToLower().EndsWith("arc")) Directory.Delete(thisDir, true); string[] IconFiles = Directory.GetFiles(TempIconPath + "arc"); @@ -2401,9 +2136,9 @@ namespace CustomizeMii { foreach (string thisDir in IconDirs) { - if (!thisDir.EndsWith("anim") && - !thisDir.EndsWith("blyt") && - !thisDir.EndsWith("timg")) + if (!thisDir.ToLower().EndsWith("anim") && + !thisDir.ToLower().EndsWith("blyt") && + !thisDir.ToLower().EndsWith("timg")) Directory.Delete(thisDir, true); } } @@ -2413,7 +2148,7 @@ namespace CustomizeMii foreach (string thisFile in AnimFiles) { - if (!thisFile.EndsWith(".brlan")) + if (!thisFile.ToLower().EndsWith(".brlan")) File.Delete(thisFile); } @@ -2425,7 +2160,7 @@ namespace CustomizeMii foreach (string thisFile in BlytFiles) { - if (!thisFile.EndsWith(".brlyt")) + if (!thisFile.ToLower().EndsWith(".brlyt")) File.Delete(thisFile); } @@ -2437,7 +2172,7 @@ namespace CustomizeMii foreach (string thisFile in TimgFiles) { - if (!thisFile.EndsWith(".tpl")) + if (!thisFile.ToLower().EndsWith(".tpl")) File.Delete(thisFile); } @@ -2452,239 +2187,46 @@ namespace CustomizeMii private void btnCreateWad_Click(object sender, EventArgs e) { - if (!string.IsNullOrEmpty(tbSourceWad.Text)) + if (pbProgress.Value == 100) { - if (cbFailureChecks.Checked == true || FailureCheck() == true) + if (!string.IsNullOrEmpty(tbSourceWad.Text)) { - SaveFileDialog sfd = new SaveFileDialog(); - sfd.Filter = "Wii Channels|*.wad"; - - if (!string.IsNullOrEmpty(tbAllLanguages.Text)) - sfd.FileName = tbAllLanguages.Text + " - " + tbTitleID.Text.ToUpper() + ".wad"; - else - sfd.FileName = tbEnglish.Text + " - " + tbTitleID.Text.ToUpper() + ".wad"; - - if (sfd.ShowDialog() == DialogResult.OK) + if (cbFailureChecks.Checked == true || FailureCheck() == true) { - try + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "Wii Channels|*.wad"; + + if (!string.IsNullOrEmpty(tbAllLanguages.Text)) + sfd.FileName = tbAllLanguages.Text + " - " + tbTitleID.Text.ToUpper() + ".wad"; + else + sfd.FileName = tbEnglish.Text + " - " + tbTitleID.Text.ToUpper() + ".wad"; + + if (sfd.ShowDialog() == DialogResult.OK) { - CreationTimer.Reset(); - CreationTimer.Start(); - NandLoader = cmbNandLoader.SelectedIndex; - BackgroundWorker bwCreateWad = new BackgroundWorker(); - bwCreateWad.DoWork += new DoWorkEventHandler(bwCreateWad_DoWork); - bwCreateWad.ProgressChanged += new ProgressChangedEventHandler(bwCreateWad_ProgressChanged); - bwCreateWad.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwCreateWad_RunWorkerCompleted); - bwCreateWad.WorkerReportsProgress = true; - bwCreateWad.RunWorkerAsync(sfd.FileName); - } - catch (Exception ex) - { - CreationTimer.Stop(); - ErrorBox(ex.Message); - } - } - } - } - } - - void bwCreateWad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - EventHandler EnableControls = new EventHandler(this.EnableControls); - EventHandler Initialize = new EventHandler(this.Initialize); - pbProgress.Value = 100; - lbStatusText.Text = string.Empty; - this.Invoke(EnableControls); - this.Invoke(Initialize); - } - - void bwCreateWad_ProgressChanged(object sender, ProgressChangedEventArgs e) - { - ProgressValue = e.ProgressPercentage; - ProgressState = (string)e.UserState; - - this.Invoke(ProgressUpdate); - } - - void bwCreateWad_DoWork(object sender, DoWorkEventArgs e) - { - try - { - BackgroundWorker bwCreateWad = sender as BackgroundWorker; - EventHandler DisableControls = new EventHandler(this.DisableControls); - this.Invoke(DisableControls); - - bwCreateWad.ReportProgress(0, "Making TPLs transparent"); - MakeBannerTplsTransparent(); - MakeIconTplsTransparent(); - - bwCreateWad.ReportProgress(5, "Packing icon.bin..."); - byte[] iconbin; - - if (!string.IsNullOrEmpty(IconReplace)) - iconbin = Wii.U8.PackU8(TempIconPath); - else - iconbin = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT"); - - if (cbLz77.Checked == true) iconbin = Wii.Lz77.Compress(iconbin); - iconbin = Wii.U8.AddHeaderIMD5(iconbin); - Wii.Tools.SaveFileFromByteArray(iconbin, TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin"); - Directory.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\icon.bin_OUT", true); - - bwCreateWad.ReportProgress(25, "Packing banner.bin..."); - byte[] bannerbin; - - if (!string.IsNullOrEmpty(BannerReplace)) - bannerbin = Wii.U8.PackU8(TempBannerPath); - else - bannerbin = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT"); - - if (cbLz77.Checked == true) bannerbin = Wii.Lz77.Compress(bannerbin); - bannerbin = Wii.U8.AddHeaderIMD5(bannerbin); - Wii.Tools.SaveFileFromByteArray(bannerbin, TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin"); - Directory.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\banner.bin_OUT", true); - - if (!string.IsNullOrEmpty(SoundReplace) || !string.IsNullOrEmpty(tbSound.Text)) - { - bwCreateWad.ReportProgress(50, "Packing sound.bin..."); - - if (!string.IsNullOrEmpty(SoundReplace)) - { - File.Delete(TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin"); - File.Copy(TempSoundPath, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin"); - } - else if (!string.IsNullOrEmpty(tbSound.Text)) - { - string SoundFile = tbSound.Text; - if (tbSound.Text.EndsWith(".mp3")) SoundFile = TempWavePath; - - Wii.Sound.WaveToSoundBin(SoundFile, TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", cbLz77.Checked); - } - } - - bwCreateWad.ReportProgress(60, "Packing 00000000.app..."); - int[] Sizes = new int[3]; - string[] Titles = new string[] { tbJapanese.Text, tbEnglish.Text, tbGerman.Text, tbFrench.Text, tbSpanish.Text, tbItalian.Text, tbDutch.Text }; - - for (int i = 0; i < Titles.Length; i++) - if (string.IsNullOrEmpty(Titles[i])) Titles[i] = tbAllLanguages.Text; - - byte[] nullapp = Wii.U8.PackU8(TempUnpackPath + "00000000.app_OUT", out Sizes[0], out Sizes[1], out Sizes[2]); - nullapp = Wii.U8.AddHeaderIMET(nullapp, Titles, Sizes); - Wii.Tools.SaveFileFromByteArray(nullapp, TempUnpackPath + "00000000.app"); - Directory.Delete(TempUnpackPath + "00000000.app_OUT", true); - - string[] tikfile = Directory.GetFiles(TempUnpackPath, "*.tik"); - string[] tmdfile = Directory.GetFiles(TempUnpackPath, "*.tmd"); - byte[] tmd = Wii.Tools.LoadFileToByteArray(tmdfile[0]); - - if (!string.IsNullOrEmpty(tbDol.Text)) - { - bwCreateWad.ReportProgress(80, "Inserting new DOL..."); - string[] AppFiles = Directory.GetFiles(TempUnpackPath, "*.app"); - - foreach (string thisApp in AppFiles) - if (!thisApp.EndsWith("00000000.app")) File.Delete(thisApp); - - if (NandLoader == 0) - { - using (BinaryReader nandloader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomizeMii.Resources.comex.app"))) - { - using (FileStream fs = new FileStream(TempUnpackPath + "\\00000001.app", FileMode.Create)) + try { - byte[] temp = nandloader.ReadBytes((int)nandloader.BaseStream.Length); - fs.Write(temp, 0, temp.Length); + CreationTimer.Reset(); + CreationTimer.Start(); + + WadCreationInfo wadInfo = new WadCreationInfo(); + wadInfo.outFile = sfd.FileName; + wadInfo.nandLoader = (WadCreationInfo.NandLoader)cmbNandLoader.SelectedIndex; + + BackgroundWorker bwCreateWad = new BackgroundWorker(); + bwCreateWad.DoWork += new DoWorkEventHandler(bwCreateWad_DoWork); + bwCreateWad.ProgressChanged += new ProgressChangedEventHandler(bwCreateWad_ProgressChanged); + bwCreateWad.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwCreateWad_RunWorkerCompleted); + bwCreateWad.WorkerReportsProgress = true; + bwCreateWad.RunWorkerAsync(wadInfo); + } + catch (Exception ex) + { + CreationTimer.Stop(); + ErrorBox(ex.Message); } } - - if (tbDol.Text.StartsWith("Simple Forwarder:")) - { - CreateForwarderSimple(TempUnpackPath + "\\00000002.app"); - } - else if (tbDol.Text.StartsWith("Complex Forwarder:")) - { - bwCreateWad.ReportProgress(82, "Compiling Forwarder..."); - CreateForwarderComplex(TempUnpackPath + "\\00000002.app"); - } - else - { - File.Copy(tbDol.Text, TempUnpackPath + "\\00000002.app"); - } - - tmd = Wii.WadEdit.ChangeTmdBootIndex(tmd, 1); - } - else - { - using (BinaryReader nandloader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomizeMii.Resources.Waninkoko.app"))) - { - using (FileStream fs = new FileStream(TempUnpackPath + "\\00000002.app", FileMode.Create)) - { - byte[] temp = nandloader.ReadBytes((int)nandloader.BaseStream.Length); - fs.Write(temp, 0, temp.Length); - } - } - - if (tbDol.Text.StartsWith("Simple Forwarder:")) - { - CreateForwarderSimple(TempUnpackPath + "\\00000001.app"); - } - else if (tbDol.Text.StartsWith("Complex Forwarder:")) - { - bwCreateWad.ReportProgress(82, "Compiling Forwarder..."); - CreateForwarderComplex(TempUnpackPath + "\\00000001.app"); - } - else - { - File.Copy(tbDol.Text, TempUnpackPath + "\\00000001.app"); - } - - tmd = Wii.WadEdit.ChangeTmdBootIndex(tmd, 2); - } - - tmd = Wii.WadEdit.ChangeTmdContentCount(tmd, 3); - - bwCreateWad.ReportProgress(85, "Updating TMD..."); - File.Delete(tmdfile[0]); - using (FileStream fs = new FileStream(tmdfile[0], FileMode.Create)) - { - byte[] tmdconts = new byte[108]; - tmdconts[7] = 0x01; - tmdconts[39] = 0x01; - tmdconts[41] = 0x01; - tmdconts[43] = 0x01; - tmdconts[75] = 0x02; - tmdconts[77] = 0x02; - tmdconts[79] = 0x01; - - fs.Write(tmd, 0, 484); - fs.Write(tmdconts, 0, tmdconts.Length); } } - - bwCreateWad.ReportProgress(85, "Updating TMD..."); - Wii.WadEdit.UpdateTmdContents(tmdfile[0]); - - Wii.WadEdit.ChangeTitleID(tikfile[0], 0, tbTitleID.Text.ToUpper()); - Wii.WadEdit.ChangeTitleID(tmdfile[0], 1, tbTitleID.Text.ToUpper()); - - bwCreateWad.ReportProgress(90, "Trucha Signing..."); - Wii.WadEdit.TruchaSign(tmdfile[0], 1); - Wii.WadEdit.TruchaSign(tikfile[0], 0); - - bwCreateWad.ReportProgress(95, "Packing WAD..."); - if (File.Exists((string)e.Argument)) File.Delete((string)e.Argument); - Wii.WadPack.PackWad(TempUnpackPath, (string)e.Argument, false); - - bwCreateWad.ReportProgress(100, " "); - CreationTimer.Stop(); - InfoBox(string.Format("Successfully created custom channel!\nTime elapsed: {0} ms", CreationTimer.ElapsedMilliseconds)); - } - catch (Exception ex) - { - CreationTimer.Stop(); - EventHandler EnableControls = new EventHandler(this.EnableControls); - this.Invoke(EnableControls); - ErrorBox(ex.Message); } } @@ -2732,61 +2274,6 @@ namespace CustomizeMii lbBrlanActions.Text = "Icon"; } - //private void btnBrlytAdd_Click(object sender, EventArgs e) - //{ - // if (!string.IsNullOrEmpty(lbBrlytActions.Text)) - // { - // OpenFileDialog ofd = new OpenFileDialog(); - // ofd.Filter = "brlyt Files|*.brlyt"; - - // if (ofd.ShowDialog() == DialogResult.OK) - // { - // try - // { - // bool Exists = false; - - // if (lbBrlytActions.Text == "Banner") - // { - // for (int i = 0; i < lbxBrlytBanner.Items.Count; i++) - // if (lbxBrlytBanner.Items[i].ToString() == ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)) - // Exists = true; - - // if (Exists == true) - // ErrorBox("This file already exists, use the Replace button!"); - // else - // { - // if (string.IsNullOrEmpty(BannerReplace)) - // File.Copy(ofd.FileName, TempUnpackBannerBrlytPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // else - // File.Copy(ofd.FileName, BannerBrlytPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // lbxBrlytBanner.Items.Add(ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // BrlytChanged = true; - // } - // } - // else - // { - // for (int i = 0; i < lbxBrlytIcon.Items.Count; i++) - // if (lbxBrlytIcon.Items[i].ToString() == ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)) - // Exists = true; - - // if (Exists == true) - // ErrorBox("This file already exists, use the Replace button!"); - // else - // { - // if (string.IsNullOrEmpty(IconReplace)) - // File.Copy(ofd.FileName, TempUnpackIconBrlytPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // else - // File.Copy(ofd.FileName, IconBrlytPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // lbxBrlytIcon.Items.Add(ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); - // BrlytChanged = true; - // } - // } - // } - // catch (Exception ex) { ErrorBox(ex.Message); } - // } - // } - //} - private void btnBrlanAdd_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(lbBrlanActions.Text)) @@ -2811,9 +2298,9 @@ namespace CustomizeMii else { if (string.IsNullOrEmpty(BannerReplace)) - File.Copy(ofd.FileName, TempUnpackBannerBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); + File.Copy(ofd.FileName, TempUnpackBannerBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1), true); else - File.Copy(ofd.FileName, BannerBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); + File.Copy(ofd.FileName, BannerBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1), true); lbxBrlanBanner.Items.Add(ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); BrlanChanged = true; } @@ -2829,9 +2316,9 @@ namespace CustomizeMii else { if (string.IsNullOrEmpty(IconReplace)) - File.Copy(ofd.FileName, TempUnpackIconBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); + File.Copy(ofd.FileName, TempUnpackIconBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1), true); else - File.Copy(ofd.FileName, IconBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); + File.Copy(ofd.FileName, IconBrlanPath + ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1), true); lbxBrlanIcon.Items.Add(ofd.FileName.Remove(0, ofd.FileName.LastIndexOf('\\') + 1)); BrlanChanged = true; } @@ -2875,7 +2362,7 @@ namespace CustomizeMii brlytFile = IconBrlytPath + lbxBrlytIcon.Items.ToString(); } - File.Copy(brlytFile, sfd.FileName); + File.Copy(brlytFile, sfd.FileName, true); } catch (Exception ex) { ErrorBox(ex.Message); } } @@ -2915,62 +2402,13 @@ namespace CustomizeMii brlanFile = IconBrlanPath + lbxBrlanIcon.Items.ToString(); } - File.Copy(brlanFile, sfd.FileName); + File.Copy(brlanFile, sfd.FileName, true); } catch (Exception ex) { ErrorBox(ex.Message); } } } } - //private void btnBrlytDelete_Click(object sender, EventArgs e) - //{ - // if (!string.IsNullOrEmpty(lbBrlytActions.Text)) - // { - // try - // { - // string brlytFile; - - // if (lbBrlytActions.Text == "Banner") - // { - // if (lbxBrlytBanner.Items.Count > 1) - // { - // if (string.IsNullOrEmpty(BannerReplace)) - // brlytFile = TempUnpackBannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString(); - // else - // brlytFile = BannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString(); - - // lbxBrlytBanner.Items.Remove(lbxBrlytBanner.SelectedItem); - // File.Delete(brlytFile); - // BrlytChanged = true; - // } - // else - // { - // ErrorBox("You can't delete the last file.\nAdd a new one first in order to delete this one."); - // } - // } - // else - // { - // if (lbxBrlytIcon.Items.Count > 1) - // { - // if (string.IsNullOrEmpty(IconReplace)) - // brlytFile = TempUnpackIconBrlytPath + lbxBrlytIcon.SelectedItem.ToString(); - // else - // brlytFile = IconBrlytPath + lbxBrlytIcon.SelectedItem.ToString(); - - // lbxBrlytIcon.Items.Remove(lbxBrlytIcon.SelectedItem); - // File.Delete(brlytFile); - // BrlytChanged = true; - // } - // else - // { - // ErrorBox("You can't delete the last file.\nAdd a new one first in order to delete this one."); - // } - // } - // } - // catch { } - // } - //} - private void btnBrlanDelete_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(lbBrlanActions.Text)) @@ -3036,13 +2474,13 @@ namespace CustomizeMii if (string.IsNullOrEmpty(BannerReplace)) { File.Delete(TempUnpackBannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString()); - File.Copy(ofd.FileName, TempUnpackBannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString()); + File.Copy(ofd.FileName, TempUnpackBannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString(), true); BrlytChanged = true; } else { File.Delete(BannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString()); - File.Copy(ofd.FileName, BannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString()); + File.Copy(ofd.FileName, BannerBrlytPath + lbxBrlytBanner.SelectedItem.ToString(), true); BrlytChanged = true; } } @@ -3051,13 +2489,13 @@ namespace CustomizeMii if (string.IsNullOrEmpty(IconReplace)) { File.Delete(TempUnpackIconBrlytPath + lbxBrlytIcon.SelectedItem.ToString()); - File.Copy(ofd.FileName, TempUnpackIconBrlytPath + lbxBrlytIcon.SelectedItem.ToString()); + File.Copy(ofd.FileName, TempUnpackIconBrlytPath + lbxBrlytIcon.SelectedItem.ToString(), true); BrlytChanged = true; } else { File.Delete(IconBrlytPath + lbxBrlytIcon.SelectedItem.ToString()); - File.Copy(ofd.FileName, IconBrlytPath + lbxBrlytIcon.SelectedItem.ToString()); + File.Copy(ofd.FileName, IconBrlytPath + lbxBrlytIcon.SelectedItem.ToString(), true); BrlytChanged = true; } } @@ -3083,13 +2521,13 @@ namespace CustomizeMii if (string.IsNullOrEmpty(BannerReplace)) { File.Delete(TempUnpackBannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString()); - File.Copy(ofd.FileName, TempUnpackBannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString()); + File.Copy(ofd.FileName, TempUnpackBannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString(), true); BrlanChanged = true; } else { File.Delete(BannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString()); - File.Copy(ofd.FileName, BannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString()); + File.Copy(ofd.FileName, BannerBrlanPath + lbxBrlanBanner.SelectedItem.ToString(), true); BrlanChanged = true; } } @@ -3098,13 +2536,13 @@ namespace CustomizeMii if (string.IsNullOrEmpty(IconReplace)) { File.Delete(TempUnpackIconBrlanPath + lbxBrlanIcon.SelectedItem.ToString()); - File.Copy(ofd.FileName, TempUnpackIconBrlanPath + lbxBrlanIcon.SelectedItem.ToString()); + File.Copy(ofd.FileName, TempUnpackIconBrlanPath + lbxBrlanIcon.SelectedItem.ToString(), true); BrlanChanged = true; } else { File.Delete(IconBrlanPath + lbxBrlanIcon.SelectedItem.ToString()); - File.Copy(ofd.FileName, IconBrlanPath + lbxBrlanIcon.SelectedItem.ToString()); + File.Copy(ofd.FileName, IconBrlanPath + lbxBrlanIcon.SelectedItem.ToString(), true); BrlanChanged = true; } } @@ -3203,7 +2641,7 @@ namespace CustomizeMii TplFormat = 5; break; default: - if (!ofd.FileName.EndsWith(".tpl")) + if (!ofd.FileName.ToLower().EndsWith(".tpl")) { ErrorBox("This format is not supported, you must choose either RGBA8, RGB565 or RGB5A3!"); return; @@ -3217,9 +2655,9 @@ namespace CustomizeMii return; } - if (ofd.FileName.EndsWith(".tpl")) + if (ofd.FileName.ToLower().EndsWith(".tpl")) { - File.Copy(ofd.FileName, CurBannerPath + "timg\\" + TplName); + File.Copy(ofd.FileName, CurBannerPath + "timg\\" + TplName, true); lbxBannerTpls.Items.Add(TplName); } else @@ -3269,7 +2707,7 @@ namespace CustomizeMii TplFormat = 5; break; default: - if (!ofd.FileName.EndsWith(".tpl")) + if (!ofd.FileName.ToLower().EndsWith(".tpl")) { ErrorBox("This format is not supported, you must choose either RGBA8, RGB565 or RGB5A3!"); return; @@ -3283,9 +2721,9 @@ namespace CustomizeMii return; } - if (ofd.FileName.EndsWith(".tpl")) + if (ofd.FileName.ToLower().EndsWith(".tpl")) { - File.Copy(ofd.FileName, CuriconPath + "timg\\" + TplName); + File.Copy(ofd.FileName, CuriconPath + "timg\\" + TplName, true); lbxIconTpls.Items.Add(TplName); } else @@ -3335,7 +2773,7 @@ namespace CustomizeMii lbxBannerTpls.Items.Remove(lbxBannerTpls.SelectedItem); lbxBannerTpls.Items.Add(thisItem + " (Transparent)"); lbxBannerTpls.SelectedItem = thisItem + " (Transparent)"; - Transparents.Add(thisItem); + BannerTransparents.Add(thisItem); } } catch { } @@ -3348,10 +2786,12 @@ namespace CustomizeMii lbxBannerTpls.Items.Remove(lbxBannerTpls.SelectedItem); lbxBannerTpls.Items.Add(thisItem.Replace(" (Transparent)", string.Empty)); lbxBannerTpls.SelectedItem = thisItem.Replace(" (Transparent)", string.Empty); - Transparents.Remove(thisItem.Replace(" (Transparent)", string.Empty)); + BannerTransparents.Remove(thisItem.Replace(" (Transparent)", string.Empty)); } catch { } } + + lbxBannerTpls.Focus(); } } @@ -3369,7 +2809,7 @@ namespace CustomizeMii lbxIconTpls.Items.Remove(lbxIconTpls.SelectedItem); lbxIconTpls.Items.Add(thisItem + " (Transparent)"); lbxIconTpls.SelectedItem = thisItem + " (Transparent)"; - Transparents.Add(thisItem); + IconTransparents.Add(thisItem); } } catch { } @@ -3382,15 +2822,22 @@ namespace CustomizeMii lbxIconTpls.Items.Remove(lbxIconTpls.SelectedItem); lbxIconTpls.Items.Add(thisItem.Replace(" (Transparent)", string.Empty)); lbxIconTpls.SelectedItem = thisItem.Replace(" (Transparent)", string.Empty); - Transparents.Remove(thisItem.Replace(" (Transparent)", string.Empty)); + IconTransparents.Remove(thisItem.Replace(" (Transparent)", string.Empty)); } catch { } } + + lbxIconTpls.Focus(); } } private void btnForwarder_Click(object sender, EventArgs e) { +#if Mono + ErrorBox("This feature doesn't work under Mono!"); +#endif + +#if !Mono if (CheckForForwardMii() == true) { if (CheckDevKit() == false) @@ -3409,6 +2856,7 @@ namespace CustomizeMii Process.Start("http://code.google.com/p/customizemii/downloads/list"); } } +#endif } private void cmForwarderItem_Click(object sender, EventArgs e) @@ -3420,5 +2868,352 @@ namespace CustomizeMii else ForwarderDialogComplex(); } + + private void btnOptionsExtract_Click(object sender, EventArgs e) + { + cmOptionsExtract.Show(MousePosition); + } + + private void cmOptionsExtract_MouseClick(object sender, EventArgs e) + { + ToolStripMenuItem cmSender = sender as ToolStripMenuItem; + + if (cmSender.OwnerItem == tsExtractImages) + { + try + { + FolderBrowserDialog fbd = new FolderBrowserDialog(); + + if (cmSender.Text.ToLower() == "both") { fbd.Description = "Select the path where the images will be extracted to. Two folders \"Banner\" and \"Icon\" will be created."; } + else { fbd.Description = "Select the path where the images will be extracted to."; } + + if (fbd.ShowDialog() == DialogResult.OK) + { + string bannerPath; + string iconPath; + + switch (cmSender.Text.ToLower()) + { + case "banner": + bannerPath = fbd.SelectedPath; + iconPath = string.Empty; + break; + case "icon": + bannerPath = string.Empty; + iconPath = fbd.SelectedPath; + break; + default: //both + bannerPath = fbd.SelectedPath + "\\Banner"; + iconPath = fbd.SelectedPath + "\\Icon"; + break; + } + + if (!string.IsNullOrEmpty(bannerPath)) + { + if (!Directory.Exists(bannerPath)) Directory.CreateDirectory(bannerPath); + string[] tplFiles = Directory.GetFiles(BannerTplPath, "*.tpl"); + Image img; + + foreach (string thisTpl in tplFiles) + { + img = Wii.TPL.ConvertFromTPL(thisTpl); + img.Save(bannerPath + "\\" + Path.GetFileNameWithoutExtension(thisTpl) + ".png", + System.Drawing.Imaging.ImageFormat.Png); + } + } + if (!string.IsNullOrEmpty(iconPath)) + { + if (!Directory.Exists(iconPath)) Directory.CreateDirectory(iconPath); + string[] tplFiles = Directory.GetFiles(IconTplPath, "*.tpl"); + Image img; + + foreach (string thisTpl in tplFiles) + { + img = Wii.TPL.ConvertFromTPL(thisTpl); + img.Save(iconPath + "\\" + Path.GetFileNameWithoutExtension(thisTpl) + ".png", + System.Drawing.Imaging.ImageFormat.Png); + } + } + + InfoBox("Extracted images successfully!"); + } + } + catch (Exception ex) { ErrorBox(ex.Message); } + } + else if (cmSender.OwnerItem == tsExtractSound) + { + try + { + SaveFileDialog sfd = new SaveFileDialog(); + if (cmSender.Name.ToLower() == "cmextractsoundasbin") { sfd.Filter = "BIN|*.bin"; sfd.FileName = "sound.bin"; } + else if (cmSender.Name.ToLower() == "cmextractsoundasaudio") + { + byte[] soundBin = Wii.Tools.LoadFileToByteArray(TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", 32, 16); + + if (soundBin[0] == 'R' && soundBin[1] == 'I' && soundBin[2] == 'F' && soundBin[3] == 'F') + { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wav"; } + else if (soundBin[0] == 'B' && soundBin[1] == 'N' && soundBin[2] == 'S' && soundBin[3] == ' ') + { sfd.Filter = "BNS|*.bns"; sfd.FileName = "sound.bns"; } + else if (soundBin[0] == 'F' && soundBin[1] == 'O' && soundBin[2] == 'R' && soundBin[3] == 'M') + { sfd.Filter = "AIFF|*.aif;*.aiff"; sfd.FileName = "sound.aif"; } + else if (soundBin[0] == 'L' && soundBin[1] == 'Z' && soundBin[2] == '7' && soundBin[3] == '7') + { + if (soundBin[9] == 'R' && soundBin[10] == 'I' && soundBin[11] == 'F' && soundBin[12] == 'F') + { sfd.Filter = "Wave|*.wav"; sfd.FileName = "sound.wav"; } + else if (soundBin[9] == 'B' && soundBin[10] == 'N' && soundBin[11] == 'S' && soundBin[12] == ' ') + { sfd.Filter = "BNS|*.bns"; sfd.FileName = "sound.bns"; } + else if (soundBin[9] == 'F' && soundBin[10] == 'O' && soundBin[11] == 'R' && soundBin[12] == 'M') + { sfd.Filter = "AIFF|*.aif;*.aiff"; sfd.FileName = "sound.aif"; } + else throw new Exception("Unsupported Audio Format!"); + } + else throw new Exception("Unsupported Audio Format!"); + + } + + if (sfd.ShowDialog() == DialogResult.OK) + { + if (sfd.FileName.ToLower().EndsWith(".bin")) + { + File.Copy(TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", sfd.FileName, true); + InfoBox("The sound.bin was successfully extraced!"); + } + else + { + Wii.Sound.SoundBinToAudio(TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", sfd.FileName); + InfoBox(string.Format("The sound.bin was successfully converted to {0}!", Path.GetFileName(sfd.FileName))); + } + } + } + catch (Exception ex) { ErrorBox(ex.Message); } + } + else //DOL + { + try + { + string[] tmdFile = Directory.GetFiles(TempUnpackPath, "*.tmd"); + byte[] tmd = Wii.Tools.LoadFileToByteArray(tmdFile[0]); + + int numContents = Wii.WadInfo.GetContentNum(tmd); + + if (numContents == 3) + { + int bootIndex = Wii.WadInfo.GetBootIndex(tmd); + string appFile = string.Empty; + + if (bootIndex == 1) + { appFile = "00000002.app"; } + else if (bootIndex == 2) + { appFile = "00000001.app"; } + + if (!string.IsNullOrEmpty(appFile)) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "Wii Executables|*.dol"; sfd.FileName = (string.IsNullOrEmpty(tbAllLanguages.Text) ? tbEnglish.Text : tbAllLanguages.Text) + ".dol"; + + if (sfd.ShowDialog() == DialogResult.OK) + { + File.Copy(TempUnpackPath + appFile, sfd.FileName, true); + InfoBox(string.Format("The DOL file was successfully extracted to {0}!", Path.GetFileName(sfd.FileName))); + } + } + else + ErrorBox("The DOL file couldn't be found!"); + } + else + ErrorBox("The DOL file couldn't be found!"); + } + catch (Exception ex) { ErrorBox(ex.Message); } + } + } + + private void cmLoadAudioFile_Click(object sender, EventArgs e) + { + if (pbProgress.Value == 100) + { + OpenFileDialog ofd = new OpenFileDialog(); + + if (File.Exists(Application.StartupPath + "\\lame.exe")) + { + ofd.Filter = "Wave Files|*.wav|Mp3 Files|*.mp3|BNS Files|*.bns|All|*.wav;*.mp3;*.bns"; + ofd.FilterIndex = 4; + } + else + { + ofd.Filter = "Wave Files|*.wav|BNS Files|*.bns|All|*.wav;*.bns"; + ofd.FilterIndex = 3; + } + + if (ofd.ShowDialog() == DialogResult.OK) + { + if (ofd.FileName.ToLower().EndsWith(".mp3")) + { + ConvertMp3ToWave(ofd.FileName); + } + else + { + SetText(tbSound, ofd.FileName); + + btnBrowseSound.Text = "Clear"; + + if (!string.IsNullOrEmpty(SoundReplace)) + { + SoundReplace = string.Empty; + if (cmbReplace.SelectedIndex == 2) SetText(tbReplace, SoundReplace); + if (File.Exists(TempSoundPath)) File.Delete(TempSoundPath); + } + } + } + } + } + + private void cmConvertToBns_Click(object sender, EventArgs e) + { + if (pbProgress.Value == 100) + { + CustomizeMii_BnsConvert bnsConvert = new CustomizeMii_BnsConvert(File.Exists(Application.StartupPath + "\\lame.exe")); + + if (bnsConvert.ShowDialog() == DialogResult.OK) + { + BnsConversionInfo bnsInfo = new BnsConversionInfo(); + + bnsInfo.AudioFile = bnsConvert.AudioFile; + bnsInfo.StereoToMono = false; + + if (bnsConvert.ChannelCount == 2) + { + if (MessageBox.Show("Do you want to convert the stereo Wave file to a mono BNS file?\nOnly the left channel will be taken.", + "Convert to Mono?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + bnsInfo.StereoToMono = true; + } + + if (bnsConvert.LoopFromAudio) + { bnsInfo.Loop = BnsConversionInfo.LoopType.FromWave; } + else if (bnsConvert.LoopManually) + { bnsInfo.LoopStartSample = bnsConvert.LoopStartSample; bnsInfo.Loop = BnsConversionInfo.LoopType.Manual; } + else bnsInfo.Loop = BnsConversionInfo.LoopType.None; + + BackgroundWorker bwConvertToBns = new BackgroundWorker(); + bwConvertToBns.WorkerReportsProgress = true; + bwConvertToBns.DoWork += new DoWorkEventHandler(bwConvertToBns_DoWork); + bwConvertToBns.ProgressChanged += new ProgressChangedEventHandler(bwConvertToBns_ProgressChanged); + bwConvertToBns.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwConvertToBns_RunWorkerCompleted); + + bwConvertToBns.RunWorkerAsync(bnsInfo); + } + } + } + + private void cmExtractWad_Click(object sender, EventArgs e) + { + FolderBrowserDialog fbd = new FolderBrowserDialog(); + string unpackDir = string.Format("{0} - {1}", Wii.WadInfo.GetChannelTitlesFromApp(TempUnpackPath + "00000000.app")[1], Wii.WadInfo.GetTitleID(Directory.GetFiles(TempUnpackPath, "*.tmd")[0], 1)); + fbd.Description = string.Format("Choose the path where the WAD will be extracted to. A folder called \"{0}\" containing the contents will be created!", unpackDir); + + if (fbd.ShowDialog() == DialogResult.OK) + { + unpackDir = fbd.SelectedPath + "\\" + unpackDir; + string[] files = Directory.GetFiles(TempUnpackPath); + if (!Directory.Exists(unpackDir)) Directory.CreateDirectory(unpackDir); + + foreach (string thisFile in files) + File.Copy(thisFile, unpackDir + "\\" + Path.GetFileName(thisFile), true); + + InfoBox("Successfully extracted WAD file!"); + } + } + + private void cmLoadDol_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Wii Executables|*.dol|Wii Channels|*.wad|All|*.dol;*.wad"; + ofd.FilterIndex = 3; + + if (ofd.ShowDialog() == DialogResult.OK) + { + if (ofd.FileName.EndsWith(".wad")) + { + try + { + byte[] wad = Wii.Tools.LoadFileToByteArray(ofd.FileName); + + int numContents = Wii.WadInfo.GetContentNum(wad); + + if (numContents == 3) + { + int bootIndex = Wii.WadInfo.GetBootIndex(wad); + string appFile = string.Empty; + + if (bootIndex == 1) + { appFile = "00000002.app"; } + else if (bootIndex == 2) + { appFile = "00000001.app"; } + + if (!string.IsNullOrEmpty(appFile)) + { + if (Directory.Exists(TempTempPath + "TempWad")) Directory.Delete(TempTempPath + "TempWad", true); + Wii.WadUnpack.UnpackWad(ofd.FileName, TempTempPath + "TempWad"); + + File.Copy(TempTempPath + "TempWad\\" + appFile, TempDolPath, true); + SetText(tbDol, ofd.FileName); + btnBrowseDol.Text = "Clear"; + } + else + ErrorBox("The DOL file couldn't be found!"); + } + else + ErrorBox("The DOL file couldn't be found!"); + } + catch (Exception ex) + { + SetText(tbDol, string.Empty); + ErrorBox(ex.Message); + } + } + else + { + SetText(tbDol, ofd.FileName); + btnBrowseDol.Text = "Clear"; + } + } + } + + private void cmDolFromSource_Click(object sender, EventArgs e) + { + try + { + string[] tmdFile = Directory.GetFiles(TempUnpackPath, "*.tmd"); + byte[] tmd = Wii.Tools.LoadFileToByteArray(tmdFile[0]); + + int numContents = Wii.WadInfo.GetContentNum(tmd); + + if (numContents == 3) + { + int bootIndex = Wii.WadInfo.GetBootIndex(tmd); + string appFile = string.Empty; + + if (bootIndex == 1) + { appFile = "00000002.app"; } + else if (bootIndex == 2) + { appFile = "00000001.app"; } + + if (!string.IsNullOrEmpty(appFile)) + { + File.Copy(TempUnpackPath + appFile, TempDolPath, true); + SetText(tbDol, "Internal"); + btnBrowseDol.Text = "Clear"; + } + else + ErrorBox("The DOL file couldn't be found!"); + } + else + ErrorBox("The DOL file couldn't be found!"); + } + catch (Exception ex) + { + SetText(tbDol, string.Empty); + btnBrowseDol.Text = "Browse..."; + ErrorBox(ex.Message); + } + } } } diff --git a/CustomizeMii/CustomizeMii_Main.resx b/CustomizeMii/CustomizeMii_Main.resx index a93fdf2..1cafef5 100644 --- a/CustomizeMii/CustomizeMii_Main.resx +++ b/CustomizeMii/CustomizeMii_Main.resx @@ -131,6 +131,15 @@ comex and Waninkoko for both their NAND Loader 105, 7 + + 228, 7 + + + 376, 7 + + + 479, 7 + 42 diff --git a/CustomizeMii/CustomizeMii_Structs.cs b/CustomizeMii/CustomizeMii_Structs.cs new file mode 100644 index 0000000..d0eab79 --- /dev/null +++ b/CustomizeMii/CustomizeMii_Structs.cs @@ -0,0 +1,35 @@ +namespace CustomizeMii +{ + public struct BnsConversionInfo + { + public enum LoopType + { + None, + FromWave, + Manual + } + + public LoopType Loop; + public int LoopStartSample; + public string AudioFile; + public bool StereoToMono; + } + + public struct WadCreationInfo + { + public enum NandLoader : int + { + comex = 0, + Waninkoko = 1 + } + + public string outFile; + public NandLoader nandLoader; + } + + public struct Progress + { + public int progressValue; + public string progressState; + } +} diff --git a/CustomizeMii/Instructions.txt b/CustomizeMii/Instructions.txt index 9b2edfd..9f4ca00 100644 --- a/CustomizeMii/Instructions.txt +++ b/CustomizeMii/Instructions.txt @@ -55,8 +55,8 @@ C, E, F, H, J, L, M, N, P, Q, W INSERTING A NEW DOL Let's bring some life into the channel. In the "Options" tab, use the browse button for a new DOL. -Either load a forwarder or the DOL of any application. Note that some channles require more than just a DOL -and thus may not work in a channel (e.g. MPlayer CE). +Either load a forwarder, the DOL of any application or a WAD to use it's DOL. Note that some applications +require more than just a DOL and thus may not work in a channel (e.g. MPlayer CE). Choose a NAND loader or just stick with the one selected (both will do fine). You can also use the built-in forwarder creation by using the forwarder button right below the browse button @@ -67,10 +67,15 @@ You need the ForwardMii.dll in order to use the forwarder creation. INSERTING A NEW SOUND -For the sound, you can either use a wave file or the sound replace function to use the sound of an -existing sound.bin/00000000.app/WAD. +For the sound, you can either use a wave or mp3 (needs lame.exe) file or the sound replace function to use +the sound of an existing sound.bin/00000000.app/WAD. If you want looped sound, open your wave file with wavosaur and add loop points before. +To save space, you can convert your wav or mp3 files to BNS. You can take the loop from a prelooped wave file +or enter the loop start point manually. Wave files must be 16bit PCM. +It is possible to directly convert stereo Wave files to mono BNS files, note that only the left channel of +the Wave will be taken. + EDITING THE BANNER/ICON (If you're an advanced user and want to edit the brlyt/brlan, do that first!) diff --git a/CustomizeMii/Properties/AssemblyInfo.cs b/CustomizeMii/Properties/AssemblyInfo.cs index 38dfbbb..a855e62 100644 --- a/CustomizeMii/Properties/AssemblyInfo.cs +++ b/CustomizeMii/Properties/AssemblyInfo.cs @@ -50,6 +50,6 @@ using System.Resources; // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] [assembly: NeutralResourcesLanguageAttribute("en")] diff --git a/CustomizeMii/Properties/Resources.Designer.cs b/CustomizeMii/Properties/Resources.Designer.cs index 4aba53d..313627d 100644 --- a/CustomizeMii/Properties/Resources.Designer.cs +++ b/CustomizeMii/Properties/Resources.Designer.cs @@ -1,21 +1,4 @@ -/* This file is part of CustomizeMii - * Copyright (C) 2009 Leathl - * - * CustomizeMii is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CustomizeMii is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Dieser Code wurde von einem Tool generiert. // Laufzeitversion:2.0.50727.4927 @@ -77,6 +60,13 @@ namespace CustomizeMii.Properties { } } + internal static System.Drawing.Bitmap btnCreateWad { + get { + object obj = ResourceManager.GetObject("btnCreateWad", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Icon CustomizeMii { get { object obj = ResourceManager.GetObject("CustomizeMii", resourceCulture); @@ -85,14 +75,14 @@ namespace CustomizeMii.Properties { } /// - /// Sucht eine lokalisierte Zeichenfolge, die {\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Arial;}} + /// Sucht eine lokalisierte Zeichenfolge, die {\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 MS Sans Serif;}} ///{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;} - ///{\*\generator Msftedit 5.41.21.2509;}\viewkind4\uc1\pard\sa200\sl276\slmult1\b\fs20 These are some basic instructions for CustomizeMii.\b0\par + ///{\*\generator Msftedit 5.41.21.2509;}\viewkind4\uc1\pard\sl276\slmult1\b\f0\fs17 These are some basic instructions for CustomizeMii.\b0\par ///\par ///\cf1 At the very beginning, let me say this again: Don't install any WADs without a proper brick protection!\cf0\par ///\par ///Ok, so you want to create your own custom channels?\par - ///First it is important to understand how the [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt. + ///First it is important to understand how [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt. /// internal static string Instructions { get { diff --git a/CustomizeMii/Properties/Resources.resx b/CustomizeMii/Properties/Resources.resx index 10c0e07..7f2b7d7 100644 --- a/CustomizeMii/Properties/Resources.resx +++ b/CustomizeMii/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\btnCreateWad.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\CustomizeMii.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/CustomizeMii/Readme.txt b/CustomizeMii/Readme.txt index 64f8ace..2b0e6b0 100644 --- a/CustomizeMii/Readme.txt +++ b/CustomizeMii/Readme.txt @@ -1,6 +1,4 @@ -CustomizeMii is a 100% legal custom channel creator for the Wii. -It's completely written by myself (some parts are based on other 100% legal codes). -Use legal Base WADs to create your own legal custom channels. +CustomizeMii is a custom channel creator for the Wii. The .NET Framework 2.0 is required to run this application! For any further information, see: http://customizemii.googlecode.com @@ -11,11 +9,22 @@ Thanks to icefire / Xuzz for the basic idea of this Application! ----------------------------------------------------------------------------------------- Changelog: +Version 2.0 + - Added BNS conversion (Mono and Stereo, with and without loop) + - Fixed MP3 conversion (some files didn't convert) + - Lz77 checkbox is now ticked by default + - Removed Lz77 compression of sound.bin as most sounds will get bigger + - Added ability to insert DOLs from any channel WAD + - Added ability to re-add the interal DOL (To switch the NAND Loader) + - Added ability to extract the contents, DOL, sound and all images + - Added displaying of approx. blocks to the success-message + - Deleted some functions of the complex forwarder as they weren't working properly + - Some bugfixes and improvements + Version 1.2 - Fixed writing/reading of channel titles, so japanese characters will work now - Added checkbox (Options tab) to turn security checks off - - Added built-in forwarder creator (Needs the ForwardMii.dll which is - separately avaiable) + - Added built-in forwarder creator (Needs the ForwardMii.dll which is separately avaiable) - You can choose MP3 files as channel sound (Needs lame.exe in application directory) - Bugfixes diff --git a/CustomizeMii/Resources/Instructions.rtf b/CustomizeMii/Resources/Instructions.rtf index dabab6d..687e0e2 100644 --- a/CustomizeMii/Resources/Instructions.rtf +++ b/CustomizeMii/Resources/Instructions.rtf @@ -57,21 +57,27 @@ C, E, F, H, J, L, M, N, P, Q, W\par \b INSERTING A NEW DOL\b0\par \par Let's bring some life into the channel. In the "Options" tab, use the browse button for a new DOL.\par -Either load a forwarder or the DOL of any application. Note that some channles require more than just a DOL\par -and thus may not work in a channel (e.g. MPlayer CE).\par +Either load a forwarder, the DOL of any application or a WAD to use it's DOL. Note that some applications\par +require more than just a DOL and thus may not work in a channel (e.g. MPlayer CE).\par Choose a NAND loader or just stick with the one selected (both will do fine).\par \par -You can also use the built-in forwarder creation by using the forwarder button right below the browse button for DOLs.\par -You need to get the ForwardMii.dll in order to use the forwarder creation.\par +You can also use the built-in forwarder creation by using the forwarder button right below the browse button\par +for DOLs.\par +You need the ForwardMii.dll in order to use the forwarder creation.\par \par \par \par \b INSERTING A NEW SOUND\b0\par \par -For the sound, you can either use a wave file or the sound replace function to use the sound of an\par -existing sound.bin/00000000.app/WAD.\par +For the sound, you can either use a wave or mp3 (needs lame.exe) file or the sound replace function to use\par +the sound of an existing sound.bin/00000000.app/WAD.\par If you want looped sound, open your wave file with wavosaur and add loop points before.\par \par +To save space, you can convert your wav or mp3 files to BNS. You can take the loop from a prelooped wave file\par +or enter the loop start point manually. Wave files must be 16bit PCM.\par +It is possible to directly convert stereo Wave files to mono BNS files, note that only the left channel of\par +the Wave will be taken.\par +\par \par \par \b EDITING THE BANNER/ICON (If you're an advanced user and want to edit the brlyt/brlan, do that first!)\b0\par diff --git a/CustomizeMii/Resources/btnCreateWad.png b/CustomizeMii/Resources/btnCreateWad.png new file mode 100644 index 0000000..85dc5b6 Binary files /dev/null and b/CustomizeMii/Resources/btnCreateWad.png differ diff --git a/CustomizeMii/Wave.cs b/CustomizeMii/Wave.cs new file mode 100644 index 0000000..238c101 --- /dev/null +++ b/CustomizeMii/Wave.cs @@ -0,0 +1,325 @@ +/* This file is part of CustomizeMii + * Copyright (C) 2009 Leathl + * + * CustomizeMii is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CustomizeMii is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; +using System.IO; + +namespace WaveFile +{ + /// + /// A class for RIFF Wave files + /// + public class Wave + { + //Private Variables + private int fmtOffset; + private int dataOffset; + private int smplOffset; + private byte[] waveFile; + + + + //Public Variables + /// + /// The Samplerate of the Wave file + /// + public int SampleRate { get { return GetSampleRate(); } } + /// + /// The Bitdepth of the Wave file + /// + public int BitDepth { get { return GetBitDepth(); } } + /// + /// The number of channels of the Wave file + /// + public int ChannelCount { get { return GetChannelCount(); } } + /// + /// The format of the Wave file's data. 1 = PCM + /// + public int DataFormat { get { return GetDataFormat(); } } + /// + /// The number of Loops in the Wave file + /// + public int LoopCount { get { return GetLoopCount(); } } + /// + /// The start sample of the first Loop (if exist) + /// + public int LoopStart { get { return GetLoopStart(); } } + + + + //Public Functions + + public Wave(string waveFile) + { + using (FileStream fs = new FileStream(waveFile, FileMode.Open)) + { + byte[] temp = new byte[fs.Length]; + fs.Read(temp, 0, temp.Length); + + this.waveFile = temp; + } + + if (!CheckWave()) throw new Exception("This is not a supported PCM Wave File!"); + + if (!GetFmtOffset()) throw new Exception("The format section couldn't be found!"); + if (!GetDataOffset()) throw new Exception("The data section couldn't be found!"); + GetSmplOffset(); + } + + public Wave(byte[] waveFile) + { + this.waveFile = waveFile; + + if (!CheckWave()) throw new Exception("This is not a supported PCM Wave File!"); + + if (!GetFmtOffset()) throw new Exception("The format section couldn't be found!"); + if (!GetDataOffset()) throw new Exception("The data section couldn't be found!"); + GetSmplOffset(); + } + + /// + /// Returns the Wave file as a Byte Array + /// + /// + public byte[] ToByteArray() + { + return waveFile; + } + + /// + /// Returns the Wave file as a Memory Stream + /// + /// + public MemoryStream ToMemoryStream() + { + return new MemoryStream(waveFile); + } + + /// + /// Returns only the audio data of the Wave file (No header or anything else) + /// + /// + public byte[] GetAllFrames() + { + int dataLength = GetDataLength(); + + MemoryStream ms = new MemoryStream(); + ms.Write(waveFile, dataOffset, dataLength); + + return ms.ToArray(); + } + + /// + /// Closes the Wave file + /// + public void Close() + { + waveFile = null; + } + + + + //Private Functions + + private int GetLoopStart() + { + if (smplOffset == -1) return 0; + + byte[] temp = new byte[4]; + + temp[0] = waveFile[smplOffset + 52]; + temp[1] = waveFile[smplOffset + 53]; + temp[2] = waveFile[smplOffset + 54]; + temp[3] = waveFile[smplOffset + 55]; + + return BitConverter.ToInt32(temp, 0); + } + + private int GetLoopCount() + { + if (smplOffset == -1) return 0; + + byte[] temp = new byte[4]; + + temp[0] = waveFile[smplOffset + 36]; + temp[1] = waveFile[smplOffset + 37]; + temp[2] = waveFile[smplOffset + 38]; + temp[3] = waveFile[smplOffset + 39]; + + return BitConverter.ToInt32(temp, 0); + } + + private bool GetSmplOffset() + { + try + { + int length = (waveFile.Length > 5004 ? (waveFile.Length - 5000) : 0); + for (int i = waveFile.Length - 4; i > length; i--) + { + if (waveFile[i] == 's' && + waveFile[i + 1] == 'm' && + waveFile[i + 2] == 'p' && + waveFile[i + 3] == 'l') + { + this.smplOffset = i; + return true; + } + } + } + catch { } + + for (int i = 0; i < waveFile.Length - 4; i++) + { + if (waveFile[i] == 's' && + waveFile[i + 1] == 'm' && + waveFile[i + 2] == 'p' && + waveFile[i + 3] == 'l') + { + this.smplOffset = i; + return true; + } + } + + this.smplOffset = -1; + return false; + } + + private bool GetFmtOffset() + { + if (waveFile[12] == 'f' && + waveFile[13] == 'm' && + waveFile[14] == 't' && + waveFile[15] == ' ') + { + this.fmtOffset = 12; + return true; + } + + int length = (waveFile.Length > 5004 ? 5000 : waveFile.Length - 4); + for (int i = 0; i < length; i++) + { + if (waveFile[i] == 'f' && + waveFile[i + 1] == 'm' && + waveFile[i + 2] == 't' && + waveFile[i + 3] == ' ') + { + this.fmtOffset = i; + return true; + } + } + + this.fmtOffset = -1; + return false; + } + + private int GetDataLength() + { + byte[] temp = new byte[4]; + + temp[0] = waveFile[dataOffset + 4]; + temp[1] = waveFile[dataOffset + 5]; + temp[2] = waveFile[dataOffset + 6]; + temp[3] = waveFile[dataOffset + 7]; + + return BitConverter.ToInt32(temp, 0); + } + + private bool GetDataOffset() + { + if (waveFile[40] == 'd' && + waveFile[41] == 'a' && + waveFile[42] == 't' && + waveFile[43] == 'a') + { + this.dataOffset = 40; + return true; + } + + for (int i = 0; i < waveFile.Length - 4; i++) + { + if (waveFile[i] == 'd' && + waveFile[i + 1] == 'a' && + waveFile[i + 2] == 't' && + waveFile[i + 3] == 'a') + { + this.dataOffset = i; + return true; + } + } + + this.dataOffset = -1; + return false; + } + + private int GetSampleRate() + { + byte[] temp = new byte[4]; + + temp[0] = waveFile[fmtOffset + 12]; + temp[1] = waveFile[fmtOffset + 13]; + temp[2] = waveFile[fmtOffset + 14]; + temp[3] = waveFile[fmtOffset + 15]; + + return BitConverter.ToInt32(temp, 0); + } + + private int GetBitDepth() + { + byte[] temp = new byte[2]; + + temp[0] = waveFile[fmtOffset + 22]; + temp[1] = waveFile[fmtOffset + 23]; + + return BitConverter.ToInt16(temp, 0); + } + + private int GetChannelCount() + { + byte[] temp = new byte[2]; + + temp[0] = waveFile[fmtOffset + 10]; + temp[1] = waveFile[fmtOffset + 11]; + + return BitConverter.ToInt16(temp, 0); + } + + private int GetDataFormat() + { + byte[] temp = new byte[2]; + + temp[0] = waveFile[fmtOffset + 8]; + temp[1] = waveFile[fmtOffset + 9]; + + return BitConverter.ToInt16(temp, 0); + } + + private bool CheckWave() + { + if (waveFile[0] != 'R' || + waveFile[1] != 'I' || + waveFile[2] != 'F' || + waveFile[3] != 'F' || + + waveFile[8] != 'W' || + waveFile[9] != 'A' || + waveFile[10] != 'V' || + waveFile[11] != 'E') return false; + + return true; + } + } +} diff --git a/CustomizeMii/Wii.cs b/CustomizeMii/Wii.cs index 89a2d58..acb172d 100644 --- a/CustomizeMii/Wii.cs +++ b/CustomizeMii/Wii.cs @@ -22,11 +22,11 @@ using System; using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Security.Cryptography; using System.Drawing; +using System.IO; using System.Net; +using System.Security.Cryptography; +using System.Text; namespace Wii { @@ -257,7 +257,8 @@ namespace Wii { if (fs.Length < length) length = (int)fs.Length; byte[] filearray = new byte[length]; - fs.Read(filearray, offset, length); + fs.Seek(offset, SeekOrigin.Begin); + fs.Read(filearray, 0, length); return filearray; } } @@ -530,6 +531,18 @@ namespace Wii return Headersize + Tools.AddPadding(GetCertSize(wadfile)); } + /// + /// Returns the title ID of the wad file. + /// + /// + /// 0 = Tik, 1 = Tmd + /// + public static string GetTitleID(string wadtiktmd, int type) + { + byte[] temp = Tools.LoadFileToByteArray(wadtiktmd); + return GetTitleID(temp, type); + } + /// /// Returns the title ID of the wad file. /// @@ -883,6 +896,23 @@ namespace Wii return contents; } + /// + /// Returns the boot index specified in the tmd + /// + /// + /// + public static int GetBootIndex(byte[] wadtmd) + { + int tmdpos = 0; + + if (IsThisWad(wadtmd)) + tmdpos = GetTmdPos(wadtmd); + + int bootIndex = Tools.HexStringToInt(wadtmd[tmdpos + 0x1e0].ToString("x2") + wadtmd[tmdpos + 0x1e1].ToString("x2")); + + return bootIndex; + } + /// /// Returns the approx. destination size on the Wii /// @@ -953,6 +983,21 @@ namespace Wii return size.Replace(",", "."); } + /// + /// Returns the approx. destination block on the Wii + /// + /// + /// + public static string GetNandBlocks(string wadtmd) + { + using (FileStream fs = new FileStream(wadtmd, FileMode.Open)) + { + byte[] temp = new byte[fs.Length]; + fs.Read(temp, 0, temp.Length); + return GetNandBlocks(temp); + } + } + /// /// Returns the approx. destination block on the Wii /// @@ -2226,26 +2271,6 @@ namespace Wii public class WadUnpack { - /// - /// Unpacks the the wad file - /// - public static void UnpackWad(string pathtowad, string destinationpath) - { - byte[] wadfile = Tools.LoadFileToByteArray(pathtowad); - UnpackWad(wadfile, destinationpath); - } - - /// - /// Unpacks the wad file to *wadpath*\wadunpack\ - /// - /// - public static void UnpackWad(string pathtowad) - { - string destinationpath = pathtowad.Remove(pathtowad.LastIndexOf('\\')); - byte[] wadfile = Tools.LoadFileToByteArray(pathtowad); - UnpackWad(wadfile, destinationpath); - } - /// /// Unpacks the 00000000.app of a wad /// @@ -2287,14 +2312,54 @@ namespace Wii throw new Exception("00000000.app couldn't be found in the Wad"); } + /// + /// Unpacks the the wad file + /// + public static void UnpackWad(string pathtowad, string destinationpath) + { + byte[] wadfile = Tools.LoadFileToByteArray(pathtowad); + UnpackWad(wadfile, destinationpath); + } + + /// + /// Unpacks the the wad file + /// + public static void UnpackWad(string pathtowad, string destinationpath, out bool hashesmatch) + { + byte[] wadfile = Tools.LoadFileToByteArray(pathtowad); + UnpackWad(wadfile, destinationpath, out hashesmatch); + } + + /// + /// Unpacks the wad file to *wadpath*\wadunpack\ + /// + /// + public static void UnpackWad(string pathtowad) + { + string destinationpath = pathtowad.Remove(pathtowad.LastIndexOf('\\')); + byte[] wadfile = Tools.LoadFileToByteArray(pathtowad); + UnpackWad(wadfile, destinationpath); + } + /// /// Unpacks the wad file /// public static void UnpackWad(byte[] wadfile, string destinationpath) + { + bool temp; + UnpackWad(wadfile, destinationpath, out temp); + } + + /// + /// Unpacks the wad file + /// + public static void UnpackWad(byte[] wadfile, string destinationpath, out bool hashesmatch) { if (destinationpath[destinationpath.Length - 1] != '\\') { destinationpath = destinationpath + "\\"; } + hashesmatch = true; + if (!Directory.Exists(destinationpath)) { Directory.CreateDirectory(destinationpath); } if (Directory.GetFiles(destinationpath, "*.app").Length > 0) @@ -2370,8 +2435,8 @@ namespace Wii byte[] thishash = sha1.ComputeHash(thiscontent); byte[] tmdhash = Tools.HexStringToByteArray(contents[i, 4]); - if (Tools.CompareByteArrays(thishash, tmdhash) == false) - throw new Exception("At least one content's hash doesn't match the hash in the Tmd!"); + if (Tools.CompareByteArrays(thishash, tmdhash) == false) hashesmatch = false; + // throw new Exception("At least one content's hash doesn't match the hash in the Tmd!"); } } @@ -5317,19 +5382,72 @@ namespace Wii /// /// /// - public static void SoundBinToWave(string soundbin, string wavefile) + public static void SoundBinToAudio(string soundbin, string audiofile) { - MemoryStream ms = new MemoryStream(Tools.LoadFileToByteArray(soundbin)); - byte[] wave = new byte[ms.Length - 32]; + FileStream fs = new FileStream(soundbin, FileMode.Open); + byte[] audio = new byte[fs.Length - 32]; int offset = 0; - ms.Seek(32, SeekOrigin.Begin); - ms.Read(wave, 0, wave.Length); + fs.Seek(32, SeekOrigin.Begin); + fs.Read(audio, 0, audio.Length); + fs.Close(); - if ((offset = Lz77.GetLz77Offset(wave)) != -1) - wave = Lz77.Decompress(wave, offset); + if ((offset = Lz77.GetLz77Offset(audio)) != -1) + audio = Lz77.Decompress(audio, offset); - Tools.SaveFileFromByteArray(wave, wavefile); + Tools.SaveFileFromByteArray(audio, audiofile); + } + + /// + /// Converts a BNS file to a sound.bin + /// + /// + /// + public static void BnsToSoundBin(string bnsFile, string soundBin, bool compress) + { + byte[] bns = Tools.LoadFileToByteArray(bnsFile); + + if (bns[0] != 'B' || bns[1] != 'N' || bns[2] != 'S') + throw new Exception("This is not a supported BNS file!"); + + if (compress) bns = Lz77.Compress(bns); + bns = U8.AddHeaderIMD5(bns); + + Tools.SaveFileFromByteArray(bns, soundBin); + } + + /// + /// Returns the length of the BNS audio file in seconds + /// + /// + /// + public static int GetBnsLength(string bnsFile) + { + byte[] temp = Tools.LoadFileToByteArray(bnsFile, 0, 100); + return GetBnsLength(temp); + } + + /// + /// Returns the length of the BNS audio file in seconds + /// + /// + /// + public static int GetBnsLength(byte[] bnsFile) + { + byte[] temp = new byte[4]; + temp[0] = bnsFile[45]; + temp[1] = bnsFile[44]; + + int sampleRate = BitConverter.ToInt16(temp, 0); + + temp[0] = bnsFile[55]; + temp[1] = bnsFile[54]; + temp[2] = bnsFile[53]; + temp[3] = bnsFile[52]; + + int sampleCount = BitConverter.ToInt32(temp, 0); + + return sampleCount / sampleRate; } }