mirror of
https://github.com/Brawl345/customizemii.git
synced 2024-11-14 12:25:13 +01:00
835 lines
35 KiB
C#
835 lines
35 KiB
C#
/* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Windows.Forms;
|
|
using libWiiSharp;
|
|
|
|
namespace CustomizeMii
|
|
{
|
|
partial class CustomizeMii_Main
|
|
{
|
|
private TransmitInfo transmitInfo;
|
|
private WadCreationInfo wadCreationInfo;
|
|
private bool internalSound;
|
|
|
|
private WAD sourceWad = new WAD();
|
|
private U8 bannerBin = new U8();
|
|
private U8 newBannerBin = new U8();
|
|
private U8 iconBin = new U8();
|
|
private U8 newIconBin = new U8();
|
|
private byte[] newSoundBin = new byte[0];
|
|
private byte[] newDol = new byte[0];
|
|
private string replacedBanner = string.Empty;
|
|
private string replacedIcon = string.Empty;
|
|
private string replacedSound = string.Empty;
|
|
|
|
void bwBannerReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
setControlText(tbReplace, replacedBanner);
|
|
}
|
|
|
|
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;
|
|
replacedBanner = (string)e.Argument;
|
|
|
|
if (replacedBanner.ToLower().EndsWith(".bin"))
|
|
{
|
|
bwBannerReplace.ReportProgress(0, "Loading banner.bin...");
|
|
newBannerBin.LoadFile(replacedBanner);
|
|
}
|
|
else if (replacedBanner.ToLower().EndsWith(".app"))
|
|
{
|
|
bwBannerReplace.ReportProgress(0, "Loading 00000000.app...");
|
|
U8 tmpU8 = U8.Load(replacedBanner);
|
|
|
|
bwBannerReplace.ReportProgress(50, "Loading banner.bin...");
|
|
for (int i = 0; i < tmpU8.NumOfNodes; i++)
|
|
if (tmpU8.StringTable[i].ToLower() == "banner.bin")
|
|
{ newBannerBin.LoadFile(tmpU8.Data[i]); break; }
|
|
}
|
|
else //wad
|
|
{
|
|
bwBannerReplace.ReportProgress(0, "Loading WAD...");
|
|
WAD tmpWad = WAD.Load(replacedBanner);
|
|
|
|
if (!tmpWad.HasBanner)
|
|
throw new Exception("CustomizeMii only handles Channel WADs!");
|
|
|
|
bwBannerReplace.ReportProgress(60, "Loading banner.bin...");
|
|
for (int i = 0; i < tmpWad.BannerApp.NumOfNodes; i++)
|
|
if (tmpWad.BannerApp.StringTable[i].ToLower() == "banner.bin")
|
|
{ newBannerBin.LoadFile(tmpWad.BannerApp.Data[i]); break; }
|
|
}
|
|
|
|
bannerTransparents.Clear();
|
|
|
|
addTpls();
|
|
addBrlyts();
|
|
addBrlans();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
replacedBanner = string.Empty;
|
|
errorBox(ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwIconReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
setControlText(tbReplace, replacedIcon);
|
|
}
|
|
|
|
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;
|
|
replacedIcon = (string)e.Argument;
|
|
|
|
bwIconReplace.ReportProgress(0);
|
|
|
|
if (replacedIcon.ToLower().EndsWith(".bin"))
|
|
{
|
|
bwIconReplace.ReportProgress(0, "Loading icon.bin...");
|
|
newIconBin.LoadFile(replacedIcon);
|
|
}
|
|
else if (replacedIcon.ToLower().EndsWith(".app"))
|
|
{
|
|
bwIconReplace.ReportProgress(0, "Loading 00000000.app...");
|
|
U8 tmpU8 = U8.Load(replacedIcon);
|
|
|
|
bwIconReplace.ReportProgress(50, "Loading icon.bin...");
|
|
for (int i = 0; i < tmpU8.NumOfNodes; i++)
|
|
if (tmpU8.StringTable[i].ToLower() == "icon.bin")
|
|
{ newIconBin.LoadFile(tmpU8.Data[i]); break; }
|
|
}
|
|
else //wad
|
|
{
|
|
bwIconReplace.ReportProgress(0, "Loading WAD...");
|
|
WAD tmpWad = WAD.Load(replacedIcon);
|
|
|
|
if (!tmpWad.HasBanner)
|
|
throw new Exception("CustomizeMii only handles Channel WADs!");
|
|
|
|
bwIconReplace.ReportProgress(60, "Loading icon.bin...");
|
|
for (int i = 0; i < tmpWad.BannerApp.NumOfNodes; i++)
|
|
if (tmpWad.BannerApp.StringTable[i].ToLower() == "icon.bin")
|
|
{ newIconBin.LoadFile(tmpWad.BannerApp.Data[i]); break; }
|
|
}
|
|
|
|
iconTransparents.Clear();
|
|
|
|
addTpls();
|
|
addBrlyts();
|
|
addBrlans();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
replacedIcon = string.Empty;
|
|
errorBox(ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwSoundReplace_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
setControlText(tbReplace, replacedSound);
|
|
}
|
|
|
|
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;
|
|
replacedSound = (string)e.Argument;
|
|
|
|
bwSoundReplace.ReportProgress(0);
|
|
|
|
if (replacedSound.ToLower().EndsWith(".bin"))
|
|
{
|
|
bwSoundReplace.ReportProgress(0, "Loading sound.bin...");
|
|
newSoundBin = File.ReadAllBytes(replacedSound);
|
|
}
|
|
else if (replacedSound.ToLower().EndsWith(".app"))
|
|
{
|
|
bwSoundReplace.ReportProgress(0, "Loading 00000000.app...");
|
|
U8 tmpU8 = U8.Load(replacedSound);
|
|
|
|
bwSoundReplace.ReportProgress(80, "Loading sound.bin...");
|
|
for (int i = 0; i < tmpU8.NumOfNodes; i++)
|
|
if (tmpU8.StringTable[i].ToLower() == "sound.bin")
|
|
{ newSoundBin = tmpU8.Data[i]; break; }
|
|
}
|
|
else
|
|
{
|
|
bwSoundReplace.ReportProgress(0, "Loading WAD...");
|
|
WAD tmpWad = WAD.Load(replacedSound);
|
|
|
|
if (!tmpWad.HasBanner)
|
|
throw new Exception("CustomizeMii only handles Channel WADs!");
|
|
|
|
bwSoundReplace.ReportProgress(90, "Loading sound.bin...");
|
|
for (int i = 0; i < tmpWad.BannerApp.NumOfNodes; i++)
|
|
if (tmpWad.BannerApp.StringTable[i].ToLower() == "sound.bin")
|
|
{ newSoundBin = tmpWad.BannerApp.Data[i]; break; }
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
replacedSound = string.Empty;
|
|
errorBox(ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwConvertToBns_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
if (!string.IsNullOrEmpty(replacedSound))
|
|
{
|
|
if (internalSound == true)
|
|
setControlText(tbSound, "BNS: Internal Sound");
|
|
else
|
|
setControlText(tbSound, "BNS: " + replacedSound);
|
|
|
|
btnBrowseSound.Text = "Clear";
|
|
|
|
if (cmbReplace.SelectedIndex == 2) setControlText(tbReplace, string.Empty);
|
|
}
|
|
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
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;
|
|
byte[] audioData = new byte[0];
|
|
|
|
if (bnsInfo.audioFile.ToLower() == "internal sound")
|
|
{
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
{
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "sound.bin")
|
|
audioData = Headers.IMD5.RemoveHeader(sourceWad.BannerApp.Data[i]);
|
|
}
|
|
|
|
internalSound = true;
|
|
}
|
|
else
|
|
audioData = File.ReadAllBytes(bnsInfo.audioFile);
|
|
|
|
bool mp3 = bnsInfo.audioFile.EndsWith(".mp3");
|
|
if (mp3 && bnsInfo.loopType == BnsConversionInfo.LoopType.FromWave) bnsInfo.loopType = BnsConversionInfo.LoopType.None;
|
|
|
|
if (mp3)
|
|
{
|
|
bwConvertToBns.ReportProgress(0, "Converting MP3...");
|
|
|
|
ProcessStartInfo lameI = new ProcessStartInfo(Application.StartupPath + Path.DirectorySeparatorChar + "lame.exe",
|
|
string.Format("--decode \"{0}\" \"{1}\"", bnsInfo.audioFile, Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav"));
|
|
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(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav"))
|
|
{
|
|
audioData = File.ReadAllBytes(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav");
|
|
File.Delete(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav");
|
|
}
|
|
else throw new Exception("Error converting MP3...");
|
|
}
|
|
|
|
bwConvertToBns.ReportProgress(0, "Converting to BNS...");
|
|
|
|
BNS bns = new BNS(audioData, bnsInfo.loopType == BnsConversionInfo.LoopType.FromWave);
|
|
bns.Progress += new EventHandler<ProgressChangedEventArgs>(bns_ProgressChanged);
|
|
|
|
bns.StereoToMono = bnsInfo.stereoToMono;
|
|
bns.Convert();
|
|
|
|
if (bnsInfo.loopType == BnsConversionInfo.LoopType.Manual && bnsInfo.loopStartSample > -1 && bnsInfo.loopStartSample < bns.TotalSampleCount)
|
|
bns.SetLoop(bnsInfo.loopStartSample);
|
|
|
|
newSoundBin = Headers.IMD5.AddHeader(bns.ToByteArray());
|
|
replacedSound = bnsInfo.audioFile;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
replacedSound = string.Empty;
|
|
if (File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav")) File.Delete(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav");
|
|
errorBox("Error during conversion:\n" + ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwConvertMp3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
if (!string.IsNullOrEmpty(replacedSound))
|
|
{
|
|
setControlText(tbSound, replacedSound);
|
|
btnBrowseSound.Text = "Clear";
|
|
|
|
if (cmbReplace.SelectedIndex == 2) setControlText(tbReplace, string.Empty);
|
|
}
|
|
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
void bwConvertMp3_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = e.ProgressPercentage;
|
|
currentProgress.progressState = (string)e.UserState;
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
void bwConvertMp3_DoWork(object sender, DoWorkEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
BackgroundWorker bwConvertMp3 = sender as BackgroundWorker;
|
|
|
|
ProcessStartInfo lameI = new ProcessStartInfo(Application.StartupPath + Path.DirectorySeparatorChar + "lame.exe",
|
|
string.Format("--decode \"{0}\" \"{1}\"", e.Argument, Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav"));
|
|
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, "Converting MP3...");
|
|
}
|
|
}
|
|
}
|
|
|
|
lame.WaitForExit();
|
|
lame.Close();
|
|
|
|
if (File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav"))
|
|
{
|
|
newSoundBin = Headers.IMD5.AddHeader(File.ReadAllBytes(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav"));
|
|
File.Delete(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav");
|
|
|
|
replacedSound = (string)e.Argument;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav")) File.Delete(Application.StartupPath + Path.DirectorySeparatorChar + "customizemii_temp.wav");
|
|
replacedSound = string.Empty;
|
|
errorBox("Error during conversion:\n" + ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwLoadChannel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
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;
|
|
initialize();
|
|
|
|
if (e.Argument is string) setControlText(tbSourceWad, (string)e.Argument);
|
|
else if (e.Argument is DownloadDataCompletedEventArgs) setControlText(tbSourceWad, (string)((DownloadDataCompletedEventArgs)e.Argument).UserState);
|
|
|
|
bwLoadChannel.ReportProgress(0, "Loading WAD...");
|
|
|
|
if (e.Argument is string) sourceWad.LoadFile((string)e.Argument);
|
|
else if (e.Argument is DownloadDataCompletedEventArgs) sourceWad.LoadFile(((DownloadDataCompletedEventArgs)e.Argument).Result);
|
|
|
|
if (!sourceWad.HasBanner)
|
|
throw new Exception("CustomizeMii only edits Channel WADs!");
|
|
|
|
int progressValue = 30;
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
{
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "banner.bin")
|
|
{
|
|
progressValue += 20;
|
|
bwLoadChannel.ReportProgress(progressValue, "Loading banner.bin...");
|
|
bannerBin.LoadFile(sourceWad.BannerApp.Data[i]);
|
|
}
|
|
else if (sourceWad.BannerApp.StringTable[i].ToLower() == "icon.bin")
|
|
{
|
|
progressValue += 20;
|
|
bwLoadChannel.ReportProgress(progressValue, "Loading icon.bin...");
|
|
iconBin.LoadFile(sourceWad.BannerApp.Data[i]);
|
|
}
|
|
}
|
|
|
|
bwLoadChannel.ReportProgress(90, "Loading Channel Information...");
|
|
setControlText(tbTitleID, sourceWad.UpperTitleID);
|
|
setControlText(tbStartupIos, ((int)sourceWad.StartupIOS).ToString());
|
|
|
|
string[] channelTitles = ((Headers.IMET)sourceWad.BannerApp.Header).GetTitles();
|
|
bool allLangs = true;
|
|
|
|
if (channelTitles[0] != channelTitles[1]) setControlText(tbJapanese, channelTitles[0]);
|
|
else allLangs = false;
|
|
if (channelTitles[2] != channelTitles[1]) setControlText(tbGerman, channelTitles[2]);
|
|
else allLangs = false;
|
|
if (channelTitles[3] != channelTitles[1]) setControlText(tbFrench, channelTitles[3]);
|
|
else allLangs = false;
|
|
if (channelTitles[4] != channelTitles[1]) setControlText(tbSpanish, channelTitles[4]);
|
|
else allLangs = false;
|
|
if (channelTitles[5] != channelTitles[1]) setControlText(tbItalian, channelTitles[5]);
|
|
else allLangs = false;
|
|
if (channelTitles[6] != channelTitles[1]) setControlText(tbDutch, channelTitles[6]);
|
|
else allLangs = false;
|
|
if (channelTitles[7] != channelTitles[1]) setControlText(tbKorean, channelTitles[7]);
|
|
|
|
if (allLangs) setControlText(tbEnglish, channelTitles[1]);
|
|
else setControlText(tbAllLanguages, channelTitles[1]);
|
|
|
|
bwLoadChannel.ReportProgress(95, "Loading Footer...");
|
|
if (sourceWad.CreationTimeUTC > new DateTime(1970, 1, 1))
|
|
setControlText(lbCreatedValue, sourceWad.CreationTimeUTC.ToString() + " (UTC)");
|
|
else setControlText(lbCreatedValue, "No Timestamp!");
|
|
|
|
addTpls();
|
|
addBrlyts();
|
|
addBrlans();
|
|
|
|
enableControls();
|
|
|
|
setControlText(btnBrowseSource, "Clear");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
setControlText(tbSourceWad, string.Empty);
|
|
errorBox(ex.Message);
|
|
}
|
|
}
|
|
|
|
void bwTransmit_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
enableControls();
|
|
|
|
if (transmitInfo.timeElapsed > 0)
|
|
{
|
|
DialogResult dlg;
|
|
|
|
if (transmitInfo.compressionRatio > 0)
|
|
dlg = MessageBox.Show(
|
|
string.Format("Transmitted {0} kB in {1} milliseconds...\nCompression Ratio: {2}%\n\nDo you want to save the wad file?",
|
|
transmitInfo.transmittedLength, transmitInfo.timeElapsed, transmitInfo.compressionRatio),
|
|
"Save File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
else
|
|
dlg = MessageBox.Show(
|
|
string.Format("Transmitted {0} kB in {1} milliseconds...\n\nDo you want to save the wad file?",
|
|
transmitInfo.transmittedLength, transmitInfo.timeElapsed),
|
|
"Save File?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
|
|
if (dlg == DialogResult.Yes)
|
|
{
|
|
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 (File.Exists(sfd.FileName)) File.Delete(sfd.FileName);
|
|
File.WriteAllBytes(sfd.FileName, wadCreationInfo.wadFile);
|
|
}
|
|
}
|
|
|
|
initialize();
|
|
}
|
|
}
|
|
|
|
void bwTransmit_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = e.ProgressPercentage;
|
|
currentProgress.progressState = (string)e.UserState;
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
void bwTransmit_DoWork(object sender, DoWorkEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
BackgroundWorker bwTransmit = sender as BackgroundWorker;
|
|
|
|
//Insert wad into stub dol
|
|
string fileName = "CMiiInstaller.dol";
|
|
byte[] fileData = CustomizeMiiInstaller.InstallerHelper.CreateInstaller(wadCreationInfo.wadFile, (byte)wadCreationInfo.transmitIos).ToArray();
|
|
|
|
//Transmit installer
|
|
Stopwatch transmitTimer = new Stopwatch();
|
|
|
|
HbcTransmitter transmitter = new HbcTransmitter(wadCreationInfo.transmitProtocol, wadCreationInfo.transmitIp);
|
|
transmitter.Progress += new EventHandler<ProgressChangedEventArgs>(transmitter_Progress);
|
|
|
|
transmitter_Progress(null, new ProgressChangedEventArgs(0, null));
|
|
transmitTimer.Start();
|
|
|
|
bool success = transmitter.TransmitFile(fileName, fileData);
|
|
|
|
transmitTimer.Stop();
|
|
|
|
if (!success) errorBox(transmitter.LastError);
|
|
else
|
|
{
|
|
transmitInfo.timeElapsed = (int)transmitTimer.ElapsedMilliseconds;
|
|
transmitInfo.compressionRatio = transmitter.CompressionRatio;
|
|
transmitInfo.transmittedLength = Math.Round(transmitter.TransmittedLength * 0.0009765625, 2);
|
|
}
|
|
}
|
|
catch (Exception ex) { errorBox(ex.Message); }
|
|
}
|
|
|
|
void transmitter_Progress(object sender, ProgressChangedEventArgs e)
|
|
{
|
|
currentProgress.progressValue = e.ProgressPercentage;
|
|
currentProgress.progressState = "Sending File...";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
}
|
|
|
|
void bwCreateWad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
|
{
|
|
if (!wadCreationInfo.sendToWii)
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
enableControls();
|
|
|
|
if (wadCreationInfo.success)
|
|
initialize();
|
|
}
|
|
else
|
|
{
|
|
if (wadCreationInfo.sendWadReady == true)
|
|
{
|
|
//Start new BackgroundWorker to Transmit
|
|
BackgroundWorker bwTransmit = new BackgroundWorker();
|
|
bwTransmit.WorkerReportsProgress = true;
|
|
bwTransmit.DoWork += new DoWorkEventHandler(bwTransmit_DoWork);
|
|
bwTransmit.ProgressChanged += new ProgressChangedEventHandler(bwTransmit_ProgressChanged);
|
|
bwTransmit.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwTransmit_RunWorkerCompleted);
|
|
bwTransmit.RunWorkerAsync();
|
|
}
|
|
else
|
|
{
|
|
currentProgress.progressValue = 100;
|
|
currentProgress.progressState = " ";
|
|
|
|
this.Invoke(ProgressUpdate);
|
|
enableControls();
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
BackgroundWorker bwCreateWad = sender as BackgroundWorker;
|
|
Stopwatch creationTimer = new Stopwatch();
|
|
creationTimer.Start();
|
|
|
|
try
|
|
{
|
|
WadCreationInfo wadInfo = (WadCreationInfo)e.Argument;
|
|
|
|
|
|
disableControls();
|
|
|
|
//Check Startup IOS
|
|
if (wadInfo.startupIos < 0 || wadInfo.startupIos > 255)
|
|
throw new Exception("Startup IOS must be between 0 and 255!");
|
|
|
|
wadInfo.success = false;
|
|
wadInfo.sendWadReady = false;
|
|
wadCreationInfo = wadInfo;
|
|
|
|
//Make TPLs transparent
|
|
makeBannerTplsTransparent();
|
|
makeIconTplsTransparent();
|
|
|
|
//Pack icon.bin
|
|
bwCreateWad.ReportProgress(0, "Packing icon.bin...");
|
|
if (string.IsNullOrEmpty(replacedIcon))
|
|
{
|
|
iconBin.AddHeaderImd5();
|
|
iconBin.Lz77Compress = wadInfo.lz77;
|
|
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "icon.bin")
|
|
{ sourceWad.BannerApp.ReplaceFile(i, iconBin.ToByteArray()); break; }
|
|
}
|
|
else
|
|
{
|
|
newIconBin.AddHeaderImd5();
|
|
newIconBin.Lz77Compress = wadInfo.lz77;
|
|
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "icon.bin")
|
|
{ sourceWad.BannerApp.ReplaceFile(i, newIconBin.ToByteArray()); break; }
|
|
}
|
|
|
|
//Pack banner.bin
|
|
bwCreateWad.ReportProgress(20, "Packing banner.bin...");
|
|
if (string.IsNullOrEmpty(replacedBanner))
|
|
{
|
|
bannerBin.AddHeaderImd5();
|
|
bannerBin.Lz77Compress = wadInfo.lz77;
|
|
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "banner.bin")
|
|
{ sourceWad.BannerApp.ReplaceFile(i, bannerBin.ToByteArray()); break; }
|
|
}
|
|
else
|
|
{
|
|
newBannerBin.AddHeaderImd5();
|
|
bannerBin.Lz77Compress = wadInfo.lz77;
|
|
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "banner.bin")
|
|
{ sourceWad.BannerApp.ReplaceFile(i, newBannerBin.ToByteArray()); break; }
|
|
}
|
|
|
|
//Pack sound.bin
|
|
bwCreateWad.ReportProgress(40, "Packing sound.bin...");
|
|
if (!string.IsNullOrEmpty(replacedSound) || !string.IsNullOrEmpty(wadInfo.sound))
|
|
{
|
|
for (int i = 0; i < sourceWad.BannerApp.NumOfNodes; i++)
|
|
if (sourceWad.BannerApp.StringTable[i].ToLower() == "sound.bin")
|
|
{ sourceWad.BannerApp.ReplaceFile(i, newSoundBin); break; }
|
|
}
|
|
|
|
//Insert new dol
|
|
if (!string.IsNullOrEmpty(wadInfo.dol))
|
|
{
|
|
bwCreateWad.ReportProgress(50, "Inserting DOL...");
|
|
sourceWad.RemoveAllContents();
|
|
|
|
if (wadInfo.nandLoader == WadCreationInfo.NandLoader.comex)
|
|
{
|
|
sourceWad.AddContent(Properties.Resources.comex, 1, 1, ContentType.Normal);
|
|
|
|
if (wadInfo.dol.StartsWith("Simple Forwarder:"))
|
|
sourceWad.AddContent(createForwarderSimple(), 2, 2, ContentType.Normal);
|
|
else if (wadInfo.dol.StartsWith("Complex Forwarder"))
|
|
{
|
|
bwCreateWad.ReportProgress(55, "Compiling Forwarder...");
|
|
sourceWad.AddContent(createForwarderComplex(), 2, 2, ContentType.Normal);
|
|
}
|
|
else
|
|
sourceWad.AddContent(newDol, 2, 2, ContentType.Normal);
|
|
|
|
sourceWad.BootIndex = 1;
|
|
}
|
|
else
|
|
{
|
|
sourceWad.AddContent(Properties.Resources.Waninkoko, 2, 2, ContentType.Normal);
|
|
|
|
if (wadInfo.dol.StartsWith("Simple Forwarder:"))
|
|
sourceWad.AddContent(createForwarderSimple(), 1, 1, ContentType.Normal);
|
|
else if (wadInfo.dol.StartsWith("Complex Forwarder"))
|
|
{
|
|
bwCreateWad.ReportProgress(55, "Compiling Forwarder...");
|
|
sourceWad.AddContent(createForwarderComplex(), 1, 1, ContentType.Normal);
|
|
}
|
|
else
|
|
sourceWad.AddContent(newDol, 1, 1, ContentType.Normal);
|
|
|
|
sourceWad.BootIndex = 2;
|
|
}
|
|
}
|
|
|
|
//Change channel information
|
|
for (int i = 0; i < wadInfo.titles.Length; i++)
|
|
if (string.IsNullOrEmpty(wadInfo.titles[i]))
|
|
wadInfo.titles[i] = wadInfo.allLangTitle;
|
|
|
|
bwCreateWad.ReportProgress(75, "Updating Channel Information...");
|
|
sourceWad.ChangeStartupIOS(wadInfo.startupIos);
|
|
sourceWad.ChangeChannelTitles(wadInfo.titles);
|
|
if (!string.IsNullOrEmpty(wadInfo.titleId))
|
|
sourceWad.ChangeTitleID(LowerTitleID.Channel, wadInfo.titleId);
|
|
|
|
sourceWad.FakeSign = true;
|
|
sourceWad.ChangeTitleKey("GottaGetSomeBeer");
|
|
|
|
//Pack WAD
|
|
bwCreateWad.ReportProgress(80, "Packing WAD...");
|
|
if (!wadInfo.sendToWii) sourceWad.Save(wadInfo.outFile);
|
|
else wadInfo.wadFile = sourceWad.ToByteArray();
|
|
|
|
bwCreateWad.ReportProgress(100, " ");
|
|
creationTimer.Stop();
|
|
|
|
if (!wadInfo.sendToWii)
|
|
{
|
|
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, sourceWad.NandBlocks));
|
|
}
|
|
else wadInfo.sendWadReady = true;
|
|
|
|
wadCreationInfo = wadInfo;
|
|
wadCreationInfo.success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
wadCreationInfo.sendWadReady = false;
|
|
creationTimer.Stop();
|
|
|
|
enableControls();
|
|
errorBox(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
}
|