diff --git a/CustomizeMii/CustomizeMii.csproj b/CustomizeMii/CustomizeMii.csproj index bf6c750..c044bae 100644 --- a/CustomizeMii/CustomizeMii.csproj +++ b/CustomizeMii/CustomizeMii.csproj @@ -76,6 +76,9 @@ CustomizeMii_ComplexForwarder.cs + + Form + Form @@ -89,6 +92,10 @@ CustomizeMii_InputBox.cs + + Form + + @@ -143,7 +150,6 @@ - diff --git a/CustomizeMii/CustomizeMii_BackgroundWorkers.cs b/CustomizeMii/CustomizeMii_BackgroundWorkers.cs index b1694a3..6e3edc3 100644 --- a/CustomizeMii/CustomizeMii_BackgroundWorkers.cs +++ b/CustomizeMii/CustomizeMii_BackgroundWorkers.cs @@ -473,6 +473,7 @@ namespace CustomizeMii string[] ChannelTitles = Wii.WadInfo.GetChannelTitles(WadFile); string TitleID = Wii.WadInfo.GetTitleID(WadFile, 1); + SetText(tbTitleID, TitleID); SetText(tbAllLanguages, ChannelTitles[1]); if (ChannelTitles[0] != ChannelTitles[1]) @@ -488,7 +489,18 @@ namespace CustomizeMii if (ChannelTitles[6] != ChannelTitles[1]) SetText(tbDutch, ChannelTitles[6]); - SetText(tbTitleID, TitleID); + string[] trailer = Directory.GetFiles(TempUnpackPath, "*.trailer"); + if (trailer.Length > 0) + { + DateTime timestamp = Wii.WadInfo.GetCreationTime(trailer[0]); + + if (timestamp > new DateTime(1970, 1, 1)) + { + SetLabel(lbCreatedValue, timestamp.ToString() + " (UTC)"); + } + else SetLabel(lbCreatedValue, "No Timestamp!"); + } + else SetLabel(lbCreatedValue, "No Timestamp!"); EventHandler AddBannerTpls = new EventHandler(this.AddBannerTpls); EventHandler AddIconTpls = new EventHandler(this.AddIconTpls); @@ -725,7 +737,7 @@ namespace CustomizeMii bwCreateWad.ReportProgress(95, "Packing WAD..."); if (File.Exists(wadInfo.outFile)) File.Delete(wadInfo.outFile); - Wii.WadPack.PackWad(TempUnpackPath, wadInfo.outFile, false); + Wii.WadPack.PackWad(TempUnpackPath, wadInfo.outFile); bwCreateWad.ReportProgress(100, " "); CreationTimer.Stop(); diff --git a/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs b/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs index 8faf26e..28d6e88 100644 --- a/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs +++ b/CustomizeMii/CustomizeMii_BnsConvert.Designer.cs @@ -51,6 +51,8 @@ namespace CustomizeMii this.tbAudioFile = new System.Windows.Forms.TextBox(); this.btnBrowseAudioFile = new System.Windows.Forms.Button(); this.gbLoop = new System.Windows.Forms.GroupBox(); + this.tbarLoopStartSample = new System.Windows.Forms.TrackBar(); + this.lbStartSample = new System.Windows.Forms.Label(); this.tbLoopStart = new System.Windows.Forms.TextBox(); this.rbEnterManually = new System.Windows.Forms.RadioButton(); this.rbFromAudioFile = new System.Windows.Forms.RadioButton(); @@ -71,15 +73,20 @@ namespace CustomizeMii this.lbSamplerate = new System.Windows.Forms.Label(); this.lbBitdepth = new System.Windows.Forms.Label(); this.cbSourceSound = new System.Windows.Forms.CheckBox(); + this.gbPrelisten = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btnPlay = new System.Windows.Forms.Button(); this.gbLoop.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.tbarLoopStartSample)).BeginInit(); this.gbWaveInfo.SuspendLayout(); + this.gbPrelisten.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.Location = new System.Drawing.Point(186, 189); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(160, 23); this.btnCancel.TabIndex = 10; @@ -90,7 +97,7 @@ namespace CustomizeMii // 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.Location = new System.Drawing.Point(15, 189); this.btnConvert.Name = "btnConvert"; this.btnConvert.Size = new System.Drawing.Size(160, 23); this.btnConvert.TabIndex = 9; @@ -127,41 +134,66 @@ namespace CustomizeMii // // gbLoop // + this.gbLoop.Controls.Add(this.tbarLoopStartSample); + this.gbLoop.Controls.Add(this.lbStartSample); 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.Location = new System.Drawing.Point(15, 70); this.gbLoop.Name = "gbLoop"; - this.gbLoop.Size = new System.Drawing.Size(331, 94); + this.gbLoop.Size = new System.Drawing.Size(331, 113); this.gbLoop.TabIndex = 14; this.gbLoop.TabStop = false; this.gbLoop.Text = "Loop"; // + // tbarLoopStartSample + // + this.tbarLoopStartSample.Enabled = false; + this.tbarLoopStartSample.Location = new System.Drawing.Point(107, 62); + this.tbarLoopStartSample.Maximum = 1059620; + this.tbarLoopStartSample.Name = "tbarLoopStartSample"; + this.tbarLoopStartSample.Size = new System.Drawing.Size(142, 45); + this.tbarLoopStartSample.TabIndex = 3; + this.tbarLoopStartSample.TickStyle = System.Windows.Forms.TickStyle.None; + this.tbarLoopStartSample.Scroll += new System.EventHandler(this.tbarLoopStartSample_Scroll); + // + // lbStartSample + // + this.lbStartSample.AutoSize = true; + this.lbStartSample.Location = new System.Drawing.Point(35, 74); + this.lbStartSample.Name = "lbStartSample"; + this.lbStartSample.Size = new System.Drawing.Size(66, 13); + this.lbStartSample.TabIndex = 2; + this.lbStartSample.Text = "(startsample)"; + // // tbLoopStart // this.tbLoopStart.Enabled = false; - this.tbLoopStart.Location = new System.Drawing.Point(227, 64); + this.tbLoopStart.Location = new System.Drawing.Point(256, 66); this.tbLoopStart.Name = "tbLoopStart"; this.tbLoopStart.Size = new System.Drawing.Size(60, 20); this.tbLoopStart.TabIndex = 1; this.tbLoopStart.Text = "0"; + this.tbLoopStart.TextChanged += new System.EventHandler(this.tbLoopStart_TextChanged); + this.tbLoopStart.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbLoopStart_KeyPress); // // rbEnterManually // this.rbEnterManually.AutoSize = true; - this.rbEnterManually.Location = new System.Drawing.Point(6, 65); + this.rbEnterManually.Location = new System.Drawing.Point(6, 59); this.rbEnterManually.Name = "rbEnterManually"; - this.rbEnterManually.Size = new System.Drawing.Size(215, 17); + this.rbEnterManually.Size = new System.Drawing.Size(95, 17); this.rbEnterManually.TabIndex = 0; - this.rbEnterManually.Text = "Enter Manually Loop Start Sample:"; + this.rbEnterManually.Text = "Enter Manually"; 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.Enabled = false; + this.rbFromAudioFile.Location = new System.Drawing.Point(6, 39); this.rbFromAudioFile.Name = "rbFromAudioFile"; this.rbFromAudioFile.Size = new System.Drawing.Size(281, 17); this.rbFromAudioFile.TabIndex = 0; @@ -200,49 +232,49 @@ namespace CustomizeMii 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.Size = new System.Drawing.Size(135, 192); 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.Location = new System.Drawing.Point(75, 157); 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.Location = new System.Drawing.Point(75, 135); 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.Location = new System.Drawing.Point(75, 113); 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.Location = new System.Drawing.Point(75, 91); 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.Location = new System.Drawing.Point(75, 69); 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.Location = new System.Drawing.Point(75, 47); this.lbSamplerateValue.Name = "lbSamplerateValue"; this.lbSamplerateValue.Size = new System.Drawing.Size(54, 13); this.lbSamplerateValue.TabIndex = 7; @@ -257,7 +289,7 @@ namespace CustomizeMii // lbStatus // this.lbStatus.AutoSize = true; - this.lbStatus.Location = new System.Drawing.Point(6, 151); + this.lbStatus.Location = new System.Drawing.Point(6, 157); this.lbStatus.Name = "lbStatus"; this.lbStatus.Size = new System.Drawing.Size(40, 13); this.lbStatus.TabIndex = 6; @@ -266,7 +298,7 @@ namespace CustomizeMii // lbLoopStart // this.lbLoopStart.AutoSize = true; - this.lbLoopStart.Location = new System.Drawing.Point(6, 130); + this.lbLoopStart.Location = new System.Drawing.Point(6, 135); this.lbLoopStart.Name = "lbLoopStart"; this.lbLoopStart.Size = new System.Drawing.Size(59, 13); this.lbLoopStart.TabIndex = 5; @@ -275,7 +307,7 @@ namespace CustomizeMii // lbLoopCount // this.lbLoopCount.AutoSize = true; - this.lbLoopCount.Location = new System.Drawing.Point(6, 109); + this.lbLoopCount.Location = new System.Drawing.Point(6, 113); this.lbLoopCount.Name = "lbLoopCount"; this.lbLoopCount.Size = new System.Drawing.Size(39, 13); this.lbLoopCount.TabIndex = 4; @@ -284,7 +316,7 @@ namespace CustomizeMii // lbFormat // this.lbFormat.AutoSize = true; - this.lbFormat.Location = new System.Drawing.Point(6, 88); + this.lbFormat.Location = new System.Drawing.Point(6, 91); this.lbFormat.Name = "lbFormat"; this.lbFormat.Size = new System.Drawing.Size(42, 13); this.lbFormat.TabIndex = 3; @@ -293,7 +325,7 @@ namespace CustomizeMii // lbChannelCount // this.lbChannelCount.AutoSize = true; - this.lbChannelCount.Location = new System.Drawing.Point(6, 67); + this.lbChannelCount.Location = new System.Drawing.Point(6, 69); this.lbChannelCount.Name = "lbChannelCount"; this.lbChannelCount.Size = new System.Drawing.Size(54, 13); this.lbChannelCount.TabIndex = 2; @@ -302,7 +334,7 @@ namespace CustomizeMii // lbSamplerate // this.lbSamplerate.AutoSize = true; - this.lbSamplerate.Location = new System.Drawing.Point(6, 46); + this.lbSamplerate.Location = new System.Drawing.Point(6, 47); this.lbSamplerate.Name = "lbSamplerate"; this.lbSamplerate.Size = new System.Drawing.Size(63, 13); this.lbSamplerate.TabIndex = 1; @@ -321,7 +353,7 @@ namespace CustomizeMii // this.cbSourceSound.AutoSize = true; this.cbSourceSound.Enabled = false; - this.cbSourceSound.Location = new System.Drawing.Point(15, 50); + this.cbSourceSound.Location = new System.Drawing.Point(15, 48); this.cbSourceSound.Name = "cbSourceSound"; this.cbSourceSound.Size = new System.Drawing.Size(170, 17); this.cbSourceSound.TabIndex = 16; @@ -329,13 +361,44 @@ namespace CustomizeMii this.cbSourceSound.UseVisualStyleBackColor = true; this.cbSourceSound.CheckedChanged += new System.EventHandler(this.cbSourceSound_CheckedChanged); // + // gbPrelisten + // + this.gbPrelisten.Controls.Add(this.label1); + this.gbPrelisten.Controls.Add(this.btnPlay); + this.gbPrelisten.Location = new System.Drawing.Point(519, 20); + this.gbPrelisten.Name = "gbPrelisten"; + this.gbPrelisten.Size = new System.Drawing.Size(135, 192); + this.gbPrelisten.TabIndex = 17; + this.gbPrelisten.TabStop = false; + this.gbPrelisten.Text = "Prelisten Loop"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(6, 25); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(123, 118); + this.label1.TabIndex = 0; + this.label1.Text = "Note:\r\n\r\nYou will only hear the looped part, not the part before.\r\nAlso, the Loop" + + " might be inaccurate (only a few samples)"; + // + // btnPlay + // + this.btnPlay.Location = new System.Drawing.Point(6, 156); + this.btnPlay.Name = "btnPlay"; + this.btnPlay.Size = new System.Drawing.Size(123, 23); + this.btnPlay.TabIndex = 13; + this.btnPlay.Text = "Play Loop"; + this.btnPlay.UseVisualStyleBackColor = true; + this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click); + // // 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.ClientSize = new System.Drawing.Size(674, 230); + this.Controls.Add(this.gbPrelisten); this.Controls.Add(this.cbSourceSound); this.Controls.Add(this.gbWaveInfo); this.Controls.Add(this.gbLoop); @@ -351,8 +414,10 @@ namespace CustomizeMii this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CustomizeMii_BnsConvert_FormClosing); this.gbLoop.ResumeLayout(false); this.gbLoop.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.tbarLoopStartSample)).EndInit(); this.gbWaveInfo.ResumeLayout(false); this.gbWaveInfo.PerformLayout(); + this.gbPrelisten.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -386,6 +451,11 @@ namespace CustomizeMii private System.Windows.Forms.Label lbSamplerateValue; private System.Windows.Forms.Label lbBitdepthValue; private System.Windows.Forms.CheckBox cbSourceSound; + private System.Windows.Forms.GroupBox gbPrelisten; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnPlay; + private System.Windows.Forms.Label lbStartSample; + private System.Windows.Forms.TrackBar tbarLoopStartSample; } } \ No newline at end of file diff --git a/CustomizeMii/CustomizeMii_BnsConvert.cs b/CustomizeMii/CustomizeMii_BnsConvert.cs index 8bdf4b6..d85cd9e 100644 --- a/CustomizeMii/CustomizeMii_BnsConvert.cs +++ b/CustomizeMii/CustomizeMii_BnsConvert.cs @@ -20,6 +20,7 @@ using System.IO; using System.Windows.Forms; using System.ComponentModel; using WaveFile; +using System.Media; namespace CustomizeMii { @@ -36,6 +37,9 @@ namespace CustomizeMii private int loopStart; private bool error = false; private bool cancelled = false; + private int sampleCount; + private SoundPlayer sPlayer; + private bool mp3LengthKnown = false; public string AudioFile { get { return tbAudioFile.Text; } } public bool LoopNone { get { return rbNone.Checked; } } @@ -53,7 +57,7 @@ namespace CustomizeMii 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.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, this.Size.Height); this.CenterToParent(); bwGatherInfo = new BackgroundWorker(); @@ -81,6 +85,19 @@ namespace CustomizeMii private void rbSelectionChanged(object sender, EventArgs e) { tbLoopStart.Enabled = rbEnterManually.Checked; + if (tbAudioFile.Text.ToLower().EndsWith(".mp3")) { tbarLoopStartSample.Enabled = (rbEnterManually.Checked && mp3LengthKnown); } + else { tbarLoopStartSample.Enabled = rbEnterManually.Checked; } + + if (!rbNone.Checked && this.Size.Width > 400) + this.Size = new System.Drawing.Size(gbPrelisten.Location.X + gbPrelisten.Size.Width + 15, this.Size.Height); + else if (rbNone.Checked && this.Size.Width > 400) + this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, this.Size.Height); + + } + + private void tbLoopStart_KeyPress(object sender, KeyPressEventArgs e) + { + e.Handled = !char.IsDigit(e.KeyChar) && e.KeyChar != '\b'; } private void btnConvert_Click(object sender, EventArgs e) @@ -98,12 +115,14 @@ namespace CustomizeMii tbLoopStart.SelectAll(); } + if (this.sPlayer != null) { this.sPlayer.Stop(); this.sPlayer.Dispose(); } this.DialogResult = DialogResult.OK; this.Close(); } private void btnCancel_Click(object sender, EventArgs e) { + if (this.sPlayer != null) { this.sPlayer.Stop(); this.sPlayer.Dispose(); } this.DialogResult = DialogResult.Cancel; this.Close(); } @@ -135,7 +154,7 @@ namespace CustomizeMii 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); + this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, this.Size.Height); } else { @@ -143,7 +162,7 @@ namespace CustomizeMii 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); + this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, this.Size.Height); } } @@ -160,6 +179,8 @@ namespace CustomizeMii if (ofd.FileName != tbAudioFile.Text) { btnConvert.Enabled = false; + tbarLoopStartSample.Enabled = false; + mp3LengthKnown = false; cbSourceSound.Checked = false; tbAudioFile.Text = ofd.FileName; @@ -177,8 +198,7 @@ namespace CustomizeMii 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); + this.Size = new System.Drawing.Size(gbWaveInfo.Location.X + gbWaveInfo.Size.Width + 15, this.Size.Height); } else if (ofd.FileName.EndsWith(".mp3")) { @@ -188,8 +208,16 @@ namespace CustomizeMii 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); + this.Size = new System.Drawing.Size(btnCancel.Location.X + btnCancel.Size.Width + 15, this.Size.Height); + + try + { + MP3Info mp3Info = new MP3Info(ofd.FileName); + tbarLoopStartSample.Maximum = mp3Info.AudioSamples; + mp3LengthKnown = true; + if (rbEnterManually.Checked) tbarLoopStartSample.Enabled = true; + } + catch { } } } } @@ -207,6 +235,9 @@ namespace CustomizeMii else { wave = new Wave((string)e.Argument); } + try { this.sampleCount = wave.SampleCount; } + catch { } + try { bitDepth = wave.BitDepth; } catch { bitDepth = -1; } @@ -262,6 +293,8 @@ namespace CustomizeMii } bool statusOk = true; + tbarLoopStartSample.Maximum = this.sampleCount; + if (rbEnterManually.Checked) tbarLoopStartSample.Enabled = true; if (bitDepth == -1) lbBitdepthValue.Text = "Error"; else lbBitdepthValue.Text = bitDepth.ToString(); @@ -352,5 +385,63 @@ namespace CustomizeMii } } } + + private void btnPlay_Click(object sender, EventArgs e) + { + if (btnPlay.Text == "Stop") + { + if (sPlayer != null) + { + sPlayer.Stop(); + sPlayer = null; + + btnPlay.Text = "Play Loop"; + } + } + else + { + try + { + int loopStart = rbFromAudioFile.Checked ? int.Parse(lbLoopStartValue.Text) : int.Parse(tbLoopStart.Text); + + Wave wave; + if (cbSourceSound.Checked) + { + using (FileStream fs = new FileStream(CustomizeMii_Main.TempUnpackPath + "00000000.app_OUT\\meta\\sound.bin", FileMode.Open)) + { + byte[] audio = new byte[fs.Length - 32]; + fs.Seek(32, SeekOrigin.Begin); + fs.Read(audio, 0, audio.Length); + + wave = new Wave(audio); + } + } + else wave = new Wave(tbAudioFile.Text); + + sPlayer = new SoundPlayer(wave.TrimStart(loopStart)); + sPlayer.PlayLooping(); + + btnPlay.Text = "Stop"; + } + catch (Exception ex) + { + sPlayer = null; + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void tbarLoopStartSample_Scroll(object sender, EventArgs e) + { + try { tbLoopStart.Text = tbarLoopStartSample.Value.ToString(); } + catch { } + } + + private void tbLoopStart_TextChanged(object sender, EventArgs e) + { + if (tbarLoopStartSample.Enabled) + try { tbarLoopStartSample.Value = int.Parse(tbLoopStart.Text); } + catch { } + } } } diff --git a/CustomizeMii/CustomizeMii_DragDrop.cs b/CustomizeMii/CustomizeMii_DragDrop.cs new file mode 100644 index 0000000..81e62aa --- /dev/null +++ b/CustomizeMii/CustomizeMii_DragDrop.cs @@ -0,0 +1,252 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Windows.Forms; +using System.Collections.Generic; + +namespace CustomizeMii +{ + partial class CustomizeMii_Main + { + private void CustomizeMii_Main_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop) && pbProgress.Value == 100) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data.Length == 1 && data[0].ToLower().EndsWith(".wad")) + e.Effect = DragDropEffects.Copy; + } + } + + private void CustomizeMii_Main_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data.Length == 1 && data[0].ToLower().EndsWith(".wad")) + { + LoadChannel(data[0]); + } + } + + private void tbReplace_DragEnter(object sender, DragEventArgs e) + { + if (!string.IsNullOrEmpty(tbSourceWad.Text)) + { + if (pbProgress.Value == 100 && e.Data.GetDataPresent(DataFormats.FileDrop)) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data.Length == 1) + { + if (data[0].ToLower().EndsWith(".wad") || + data[0].ToLower().EndsWith("00000000.app")) + e.Effect = DragDropEffects.Copy; + else if ((cmbReplace.SelectedIndex == 2 && data[0].ToLower().EndsWith("sound.bin")) || + (cmbReplace.SelectedIndex == 1 && data[0].ToLower().EndsWith("icon.bin")) || + (cmbReplace.SelectedIndex == 0 && data[0].ToLower().EndsWith("banner.bin"))) + e.Effect = DragDropEffects.Copy; + } + } + } + } + + private void tbReplace_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data.Length == 1 && (data[0].ToLower().EndsWith(".wad") || + data[0].ToLower().EndsWith("00000000.app") || + data[0].ToLower().EndsWith("sound.bin") || + data[0].ToLower().EndsWith("icon.bin") || + data[0].ToLower().EndsWith("banner.bin"))) + { + ReplacePart(data[0]); + } + } + + private void tbDol_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop) && pbProgress.Value == 100) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data.Length == 1 && (data[0].ToLower().EndsWith(".wad") || data[0].ToLower().EndsWith(".dol"))) + e.Effect = DragDropEffects.Copy; + } + } + + private void tbDol_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data[0].ToLower().EndsWith(".wad")) + { + try + { + byte[] wad = Wii.Tools.LoadFileToByteArray(data[0]); + + 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(data[0], TempTempPath + "TempWad"); + + File.Copy(TempTempPath + "TempWad\\" + appFile, TempDolPath, true); + SetText(tbDol, data[0]); + 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 if (data[0].ToLower().EndsWith(".dol")) + { + SetText(tbDol, data[0]); + btnBrowseDol.Text = "Clear"; + } + } + + private void tbSound_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop) && pbProgress.Value == 100) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (File.Exists(Application.StartupPath + "\\lame.exe")) + { + if (data.Length == 1 && (data[0].ToLower().EndsWith(".wav") || + data[0].ToLower().EndsWith(".bns") || + data[0].ToLower().EndsWith(".mp3"))) + e.Effect = DragDropEffects.Copy; + } + else + { + if (data.Length == 1 && (data[0].ToLower().EndsWith(".wav") || + data[0].ToLower().EndsWith(".bns"))) + e.Effect = DragDropEffects.Copy; + } + } + } + + private void tbSound_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (data[0].ToLower().EndsWith(".mp3")) + { + ConvertMp3ToWave(data[0]); + } + else + { + SetText(tbSound, data[0]); + + 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 lbxBannerTpls_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop) && pbProgress.Value == 100) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + bool correct = true; + + for (int i = 0; i < data.Length; i++) + if (!(data[0].ToLower().EndsWith(".tpl") || + data[0].ToLower().EndsWith(".png") || + data[0].ToLower().EndsWith(".jpg") || + data[0].ToLower().EndsWith(".gif") || + data[0].ToLower().EndsWith(".bmp"))) + correct = false; + + if (correct) e.Effect = DragDropEffects.Copy; + } + } + + private void lbxBannerTpls_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + List errors = new List(); + + foreach (string thisFile in data) + { + try + { + AddTpl(lbxBannerTpls, thisFile); + } + catch { errors.Add(thisFile); } + } + + if (errors.Count > 0) + { + ErrorBox(string.Format("These files were not added, because either they already exist or an error occured during conversion:\n\n{0}", string.Join("\n", (errors.ToArray())))); + } + } + + private void lbxIconTpls_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop) && pbProgress.Value == 100) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + bool correct = true; + + for (int i = 0; i < data.Length; i++) + if (!(data[0].ToLower().EndsWith(".tpl") || + data[0].ToLower().EndsWith(".png") || + data[0].ToLower().EndsWith(".jpg") || + data[0].ToLower().EndsWith(".gif") || + data[0].ToLower().EndsWith(".bmp"))) + correct = false; + + if (correct) e.Effect = DragDropEffects.Copy; + } + } + + private void lbxIconTpls_DragDrop(object sender, DragEventArgs e) + { + string[] data = (string[])e.Data.GetData(DataFormats.FileDrop); + List errors = new List(); + + foreach (string thisFile in data) + { + try + { + AddTpl(lbxIconTpls, thisFile); + } + catch { errors.Add(thisFile); } + } + + if (errors.Count > 0) + { + ErrorBox(string.Format("These files were not added, because either they already exist or an error occured during conversion:\n\n{0}", string.Join("\n", (errors.ToArray())))); + } + } + } +} diff --git a/CustomizeMii/CustomizeMii_InputBox.cs b/CustomizeMii/CustomizeMii_InputBox.cs index edf7c7d..0969964 100644 --- a/CustomizeMii/CustomizeMii_InputBox.cs +++ b/CustomizeMii/CustomizeMii_InputBox.cs @@ -46,7 +46,7 @@ namespace CustomizeMii private void CustomizeMii_InputBox_Load(object sender, EventArgs e) { - this.CenterToScreen(); + this.CenterToParent(); } private void btnExit_Click(object sender, EventArgs e) diff --git a/CustomizeMii/CustomizeMii_Main.Designer.cs b/CustomizeMii/CustomizeMii_Main.Designer.cs index eb469d0..5b1273b 100644 --- a/CustomizeMii/CustomizeMii_Main.Designer.cs +++ b/CustomizeMii/CustomizeMii_Main.Designer.cs @@ -50,6 +50,8 @@ namespace CustomizeMii this.btnCreateWad = new System.Windows.Forms.Button(); this.tabControl = new System.Windows.Forms.TabControl(); this.tabSource = new System.Windows.Forms.TabPage(); + this.lbCreatedValue = new System.Windows.Forms.Label(); + this.lbCreated = new System.Windows.Forms.Label(); this.tbReplace = new System.Windows.Forms.TextBox(); this.btnBrowseReplace = new System.Windows.Forms.Button(); this.cmbReplace = new System.Windows.Forms.ComboBox(); @@ -218,6 +220,8 @@ namespace CustomizeMii // // tabSource // + this.tabSource.Controls.Add(this.lbCreatedValue); + this.tabSource.Controls.Add(this.lbCreated); this.tabSource.Controls.Add(this.tbReplace); this.tabSource.Controls.Add(this.btnBrowseReplace); this.tabSource.Controls.Add(this.cmbReplace); @@ -236,19 +240,39 @@ namespace CustomizeMii this.tabSource.Text = "Source"; this.tabSource.UseVisualStyleBackColor = true; // + // lbCreatedValue + // + this.lbCreatedValue.AutoSize = true; + this.lbCreatedValue.Location = new System.Drawing.Point(125, 45); + this.lbCreatedValue.Name = "lbCreatedValue"; + this.lbCreatedValue.Size = new System.Drawing.Size(0, 13); + this.lbCreatedValue.TabIndex = 12; + // + // lbCreated + // + this.lbCreated.AutoSize = true; + this.lbCreated.Location = new System.Drawing.Point(8, 45); + this.lbCreated.Name = "lbCreated"; + this.lbCreated.Size = new System.Drawing.Size(111, 13); + this.lbCreated.TabIndex = 11; + this.lbCreated.Text = "Created / Last Edited:"; + // // tbReplace // - this.tbReplace.Location = new System.Drawing.Point(100, 173); + this.tbReplace.AllowDrop = true; + this.tbReplace.Location = new System.Drawing.Point(100, 177); this.tbReplace.Name = "tbReplace"; this.tbReplace.ReadOnly = true; this.tbReplace.Size = new System.Drawing.Size(254, 20); this.tbReplace.TabIndex = 10; this.tbReplace.Tag = "Disabled"; this.tbReplace.TextChanged += new System.EventHandler(this.tbReplace_TextChanged); + this.tbReplace.DragDrop += new System.Windows.Forms.DragEventHandler(this.tbReplace_DragDrop); + this.tbReplace.DragEnter += new System.Windows.Forms.DragEventHandler(this.tbReplace_DragEnter); // // btnBrowseReplace // - this.btnBrowseReplace.Location = new System.Drawing.Point(360, 171); + this.btnBrowseReplace.Location = new System.Drawing.Point(360, 175); this.btnBrowseReplace.Name = "btnBrowseReplace"; this.btnBrowseReplace.Size = new System.Drawing.Size(75, 23); this.btnBrowseReplace.TabIndex = 9; @@ -264,7 +288,7 @@ namespace CustomizeMii "Banner", "Icon", "Sound"}); - this.cmbReplace.Location = new System.Drawing.Point(11, 172); + this.cmbReplace.Location = new System.Drawing.Point(11, 176); this.cmbReplace.Name = "cmbReplace"; this.cmbReplace.Size = new System.Drawing.Size(83, 21); this.cmbReplace.TabIndex = 7; @@ -272,7 +296,7 @@ namespace CustomizeMii // // btnSaveBaseWad // - this.btnSaveBaseWad.Location = new System.Drawing.Point(360, 127); + this.btnSaveBaseWad.Location = new System.Drawing.Point(360, 142); this.btnSaveBaseWad.Name = "btnSaveBaseWad"; this.btnSaveBaseWad.Size = new System.Drawing.Size(75, 23); this.btnSaveBaseWad.TabIndex = 6; @@ -282,7 +306,7 @@ namespace CustomizeMii // // btnPreviewBaseWad // - this.btnPreviewBaseWad.Location = new System.Drawing.Point(360, 93); + this.btnPreviewBaseWad.Location = new System.Drawing.Point(360, 106); this.btnPreviewBaseWad.Name = "btnPreviewBaseWad"; this.btnPreviewBaseWad.Size = new System.Drawing.Size(75, 23); this.btnPreviewBaseWad.TabIndex = 5; @@ -292,7 +316,7 @@ namespace CustomizeMii // // btnLoadBaseWad // - this.btnLoadBaseWad.Location = new System.Drawing.Point(360, 59); + this.btnLoadBaseWad.Location = new System.Drawing.Point(360, 70); this.btnLoadBaseWad.Name = "btnLoadBaseWad"; this.btnLoadBaseWad.Size = new System.Drawing.Size(75, 23); this.btnLoadBaseWad.TabIndex = 4; @@ -318,14 +342,14 @@ namespace CustomizeMii "WADder Base 3", "UniiLoader", "Backup Channel"}); - this.lbxBaseWads.Location = new System.Drawing.Point(11, 51); + this.lbxBaseWads.Location = new System.Drawing.Point(11, 70); this.lbxBaseWads.Name = "lbxBaseWads"; - this.lbxBaseWads.Size = new System.Drawing.Size(343, 108); + this.lbxBaseWads.Size = new System.Drawing.Size(343, 95); this.lbxBaseWads.TabIndex = 3; // // btnBrowseSource // - this.btnBrowseSource.Location = new System.Drawing.Point(360, 13); + this.btnBrowseSource.Location = new System.Drawing.Point(360, 12); this.btnBrowseSource.Name = "btnBrowseSource"; this.btnBrowseSource.Size = new System.Drawing.Size(75, 23); this.btnBrowseSource.TabIndex = 2; @@ -335,7 +359,7 @@ namespace CustomizeMii // // tbSourceWad // - this.tbSourceWad.Location = new System.Drawing.Point(84, 15); + this.tbSourceWad.Location = new System.Drawing.Point(84, 14); this.tbSourceWad.Name = "tbSourceWad"; this.tbSourceWad.ReadOnly = true; this.tbSourceWad.Size = new System.Drawing.Size(270, 20); @@ -345,7 +369,7 @@ namespace CustomizeMii // lbSource // this.lbSource.AutoSize = true; - this.lbSource.Location = new System.Drawing.Point(8, 18); + this.lbSource.Location = new System.Drawing.Point(8, 17); this.lbSource.Name = "lbSource"; this.lbSource.Size = new System.Drawing.Size(70, 13); this.lbSource.TabIndex = 0; @@ -613,12 +637,15 @@ namespace CustomizeMii // // tbSound // + this.tbSound.AllowDrop = true; this.tbSound.Location = new System.Drawing.Point(90, 147); this.tbSound.Name = "tbSound"; this.tbSound.ReadOnly = true; this.tbSound.Size = new System.Drawing.Size(264, 20); this.tbSound.TabIndex = 8; this.tbSound.Tag = "Disabled"; + this.tbSound.DragDrop += new System.Windows.Forms.DragEventHandler(this.tbSound_DragDrop); + this.tbSound.DragEnter += new System.Windows.Forms.DragEventHandler(this.tbSound_DragEnter); // // cmbNandLoader // @@ -644,12 +671,15 @@ namespace CustomizeMii // // tbDol // + this.tbDol.AllowDrop = true; this.tbDol.Location = new System.Drawing.Point(90, 83); this.tbDol.Name = "tbDol"; this.tbDol.ReadOnly = true; this.tbDol.Size = new System.Drawing.Size(264, 20); this.tbDol.TabIndex = 5; this.tbDol.Tag = "Disabled"; + this.tbDol.DragDrop += new System.Windows.Forms.DragEventHandler(this.tbDol_DragDrop); + this.tbDol.DragEnter += new System.Windows.Forms.DragEventHandler(this.tbDol_DragEnter); // // tbTitleID // @@ -805,6 +835,7 @@ namespace CustomizeMii // // lbxBannerTpls // + this.lbxBannerTpls.AllowDrop = true; this.lbxBannerTpls.FormattingEnabled = true; this.lbxBannerTpls.Location = new System.Drawing.Point(11, 12); this.lbxBannerTpls.Name = "lbxBannerTpls"; @@ -812,6 +843,8 @@ namespace CustomizeMii this.lbxBannerTpls.Sorted = true; this.lbxBannerTpls.TabIndex = 0; this.lbxBannerTpls.SelectedIndexChanged += new System.EventHandler(this.lbxBannerTpls_SelectedIndexChanged); + this.lbxBannerTpls.DragDrop += new System.Windows.Forms.DragEventHandler(this.lbxBannerTpls_DragDrop); + this.lbxBannerTpls.DragEnter += new System.Windows.Forms.DragEventHandler(this.lbxBannerTpls_DragEnter); // // tabIcon // @@ -922,6 +955,7 @@ namespace CustomizeMii // // lbxIconTpls // + this.lbxIconTpls.AllowDrop = true; this.lbxIconTpls.FormattingEnabled = true; this.lbxIconTpls.Location = new System.Drawing.Point(11, 12); this.lbxIconTpls.Name = "lbxIconTpls"; @@ -929,6 +963,8 @@ namespace CustomizeMii this.lbxIconTpls.Sorted = true; this.lbxIconTpls.TabIndex = 6; this.lbxIconTpls.SelectedIndexChanged += new System.EventHandler(this.lbxIconTpls_SelectedIndexChanged); + this.lbxIconTpls.DragDrop += new System.Windows.Forms.DragEventHandler(this.lbxIconTpls_DragDrop); + this.lbxIconTpls.DragEnter += new System.Windows.Forms.DragEventHandler(this.lbxIconTpls_DragEnter); // // tabBrlyt // @@ -1442,6 +1478,7 @@ namespace CustomizeMii // // CustomizeMii_Main // + this.AllowDrop = true; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(451, 290); @@ -1454,6 +1491,8 @@ namespace CustomizeMii this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "CustomizeMii X by Leathl"; this.Load += new System.EventHandler(this.CustomizeMii_Main_Load); + this.DragDrop += new System.Windows.Forms.DragEventHandler(this.CustomizeMii_Main_DragDrop); + this.DragEnter += new System.Windows.Forms.DragEventHandler(this.CustomizeMii_Main_DragEnter); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CustomizeMii_Main_FormClosing); this.tabControl.ResumeLayout(false); this.tabSource.ResumeLayout(false); @@ -1607,6 +1646,8 @@ namespace CustomizeMii private System.Windows.Forms.ToolStripMenuItem cmDolFromSource; private System.Windows.Forms.Panel panCredits; private System.Windows.Forms.Label lbForwardMiiVersion; + private System.Windows.Forms.Label lbCreated; + private System.Windows.Forms.Label lbCreatedValue; } } diff --git a/CustomizeMii/CustomizeMii_Main.cs b/CustomizeMii/CustomizeMii_Main.cs index d6cfba6..87556d8 100644 --- a/CustomizeMii/CustomizeMii_Main.cs +++ b/CustomizeMii/CustomizeMii_Main.cs @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -//#define Mono //Change all "\\" to "/" (in all files, without quotes) while compiling for OS X / Linux (Mono) +//#define Mono //Change all "\\" to "/" (in all files; without quotes) while compiling for OS X / Linux (Mono) //#define Debug //Always remember to turn off :) using System; @@ -45,6 +45,7 @@ namespace CustomizeMii #endregion #region Variables + public bool Mono = false; 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\\"; @@ -87,6 +88,7 @@ namespace CustomizeMii private Forwarder.Complex ComplexForwarder = new Forwarder.Complex(); private delegate void BoxInvoker(string message); private delegate void SetTextInvoker(string text, TextBox tb); + private delegate void SetLabelInvoker(string text, Label lb); private double separatorBtn; private Timer tmrCredits = new Timer(); private ToolTip tTip = new ToolTip(); @@ -100,17 +102,21 @@ namespace CustomizeMii private void CustomizeMii_Main_Load(object sender, EventArgs e) { + MethodInvoker Update = new MethodInvoker(UpdateCheck); + UpdatePaths(); - UpdateCheck(); + Update.BeginInvoke(null, null); #if !Mono - UpdateCheckForwardMii(); + MethodInvoker FUpdate = new MethodInvoker(UpdateCheckForwardMii); + FUpdate.BeginInvoke(null, null); CommonKeyCheck(); #endif InitializeStartup(); #if Mono + Mono = true; //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. + */ + +using System; +using System.Collections; +using System.IO; + +class MP3Info +{ + //Private Variables + private int fileSize; + private int headerPos; + private BitArray bitHeader; + private MpegVersion mpegVersion; + private MpegLayer mpegLayer; + private int bitrate; + private int frequency; + private bool paddingBit; + private int frameLength; + private int frameCount; + private double secLength; + private int waveSamples; + + //Public Variables + public int FileSize { get { return fileSize; } } + public MpegVersion MPEGVersion { get { return mpegVersion; } } + public MpegLayer MPEGLayer { get { return mpegLayer; } } + public int Bitrate { get { return bitrate; } } + public int Frequency { get { return frequency; } } + public int FrameLength { get { return frameLength; } } + public int FrameCount { get { return frameCount; } } + public double Seconds { get { return secLength; } } + public int AudioSamples { get { return waveSamples; } } + + //Public Functions + public MP3Info(string mp3File) + { + FileInfo fi = new FileInfo(mp3File); + this.fileSize = (int)fi.Length; + + FileStream fs = fi.OpenRead(); + fs.Seek(0, SeekOrigin.Begin); + + this.headerPos = SearchHeader(fs); + + byte[] header = new byte[4]; + fs.Seek(this.headerPos, SeekOrigin.Begin); + fs.Read(header, 0, header.Length); + fs.Close(); + + GetHeaderBits(header); + LoadHeader(); + } + + public MP3Info(byte[] mp3Header) + { + GetHeaderBits(mp3Header); + LoadHeader(); + } + + //Private Functions + private void ShowHeader() + { + //For debugging + if (this.bitHeader != null) + { + string strBits = string.Empty; + foreach (bool x in this.bitHeader) + if (x) strBits += "1"; else strBits += "0"; + + for (int i = strBits.Length - 8; i >= 0; i -= 8) + strBits = strBits.Insert(i, " "); + + System.Windows.Forms.MessageBox.Show(strBits); + } + } + + private int SearchHeader(Stream fileStream) + { + int tmp; + + while ((tmp = fileStream.ReadByte()) != -1) + { + if (tmp == 255) + { + tmp = fileStream.ReadByte(); + BitArray tmpBits = new BitArray(new int[] { tmp }); + if (tmpBits[7] && tmpBits[6] && tmpBits[5]) return (int)(fileStream.Position - 2); + } + } + + throw new Exception("Frame Header couldn't be found!"); + } + + private void GetHeaderBits(byte[] fourBytes) + { + BitArray tmp = new BitArray(fourBytes); + this.bitHeader = new BitArray(4 * 8); + int count = 0; + + for (int i = 0; i < 32; i += 8) + for (int j = 7; j >= 0; j--) + this.bitHeader[count++] = tmp[i + j]; + } + + private void LoadHeader() + { + GetVersion(this.bitHeader[11], this.bitHeader[12]); + if (this.mpegVersion == MpegVersion.Reserved) throw new NotSupportedException("Unsupported MPEG Version!"); + GetLayer(this.bitHeader[13], this.bitHeader[14]); + if (this.mpegLayer == MpegLayer.Reserved) throw new NotSupportedException("Unsupported MPEG Layer!"); + GetBitrate(this.bitHeader[16], this.bitHeader[17], this.bitHeader[18], this.bitHeader[19]); + if (this.bitrate == 0) throw new NotSupportedException("Unsupported Bitrate!"); + GetFrequency(this.bitHeader[20], this.bitHeader[21]); + if (this.frequency == -1) throw new NotSupportedException("Unsupported Frequency"); + this.paddingBit = this.bitHeader[22]; + + GetFrameLength(); + GetFrameCount(); + GetSeconds(); + GetWaveSamples(); + } + + private void GetVersion(params bool[] twoBits) + { + if (twoBits[0] && twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion1; + else if (twoBits[0] && !twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion2; + else if (!twoBits[0] && twoBits[1]) this.mpegVersion = MpegVersion.Reserved; + else if (!twoBits[0] && !twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion25; + } + + private void GetLayer(params bool[] twoBits) + { + if (twoBits[0] && twoBits[1]) this.mpegLayer = MpegLayer.I; + else if (twoBits[0] && !twoBits[1]) this.mpegLayer = MpegLayer.II; + else if (!twoBits[0] && twoBits[1]) this.mpegLayer = MpegLayer.III; + else if (!twoBits[0] && !twoBits[1]) this.mpegLayer = MpegLayer.Reserved; + } + + private void GetBitrate(params bool[] fourBits) + { + int[] bitrateTable = GetBitrateTable(); + + Array.Reverse(fourBits); + BitArray bArray = new BitArray(fourBits); + byte[] index = new byte[1]; + bArray.CopyTo(index, 0); + + this.bitrate = bitrateTable[index[0]]; + } + + private int[] GetBitrateTable() + { + if (this.mpegVersion == MpegVersion.MpegVersion1) + { + if (this.mpegLayer == MpegLayer.I) return new int[] { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }; + if (this.mpegLayer == MpegLayer.II) return new int[] { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }; + if (this.mpegLayer == MpegLayer.III) return new int[] { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }; + } + else + { + if (this.mpegLayer == MpegLayer.I) return new int[] { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }; + if (this.mpegLayer == MpegLayer.II || + this.mpegLayer == MpegLayer.III) return new int[] { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }; + } + + throw new NotSupportedException("Unsupported MPEG Version or Layer!"); + } + + private void GetFrequency(params bool[] twoBits) + { + int[] frequencyTable = GetFrequencyTable(); + + Array.Reverse(twoBits); + BitArray bArray = new BitArray(twoBits); + byte[] index = new byte[1]; + bArray.CopyTo(index, 0); + + this.frequency = frequencyTable[index[0]]; + } + + private int[] GetFrequencyTable() + { + if (this.mpegVersion == MpegVersion.MpegVersion1) + return new int[] { 44100, 48000, 32000, -1 }; + else if (this.mpegVersion == MpegVersion.MpegVersion2) + return new int[] { 22050, 24000, 16000, -1 }; + else if (this.mpegVersion == MpegVersion.MpegVersion25) + return new int[] { 32000, 16000, 8000, -1 }; + else + return new int[] { 0, 0, 0, -1 }; + } + + private void GetFrameLength() + { + double frmSize = (double)((this.mpegLayer == MpegLayer.I ? 12 : 144) * ((1000.0 * (float)this.bitrate / (float)this.frequency))); + this.frameLength = (int)Math.Ceiling(frmSize); + } + + private void GetFrameCount() + { + this.frameCount = (this.fileSize - this.headerPos) / this.frameLength; + } + + private void GetSeconds() + { + this.secLength = ((this.fileSize - this.headerPos) * 8.00) / (1000.00 * this.bitrate); + } + + private void GetWaveSamples() + { + this.waveSamples = this.frameCount * 1125; + } + + //Structs & Enums + public enum MpegVersion : int + { + Reserved = 0, + MpegVersion1 = 1, + MpegVersion25 = 2, + MpegVersion2 = 3 + } + + public enum MpegLayer : int + { + Reserved = 0, + I = 1, + II = 2, + III = 3 + } +} diff --git a/CustomizeMii/Readme.txt b/CustomizeMii/Readme.txt index eb9fcdf..8aa5eed 100644 --- a/CustomizeMii/Readme.txt +++ b/CustomizeMii/Readme.txt @@ -11,7 +11,10 @@ Changelog: Version 2.1 - Replaced the TPL preview window with the one from ShowMiiWads for easier handling - - + - Added loop prelistening to the BNS conversion window (only for wave files) + - Added drag & drop ability cause the file dialogs kept bothering me + - Improvement in startup speed (thanks shadow1643) + - Added Unix timestamp as footer (interesting to know when channels were created, huh?) - Little improvements Version 2.01 diff --git a/CustomizeMii/Wave.cs b/CustomizeMii/Wave.cs index 238c101..f940085 100644 --- a/CustomizeMii/Wave.cs +++ b/CustomizeMii/Wave.cs @@ -58,6 +58,10 @@ namespace WaveFile /// The start sample of the first Loop (if exist) /// public int LoopStart { get { return GetLoopStart(); } } + /// + /// The total number of Frames + /// + public int SampleCount { get { return GetFrameCount(); } } @@ -123,6 +127,42 @@ namespace WaveFile return ms.ToArray(); } + /// + /// Trims the start of the wave to the given sample + /// + /// + /// + public MemoryStream TrimStart(int newStartSample) + { + if (newStartSample > this.SampleCount) throw new Exception(string.Format("The loop start sample ({0}) is higher than the total number of samples ({1}) in this file!", newStartSample, this.SampleCount)); + + MemoryStream msOut = new MemoryStream(); + msOut.Seek(0, SeekOrigin.Begin); + + if (newStartSample == 0) + { + msOut.Write(waveFile, 0, waveFile.Length); + msOut.Seek(0, SeekOrigin.Begin); + return msOut; + } + + msOut.Write(waveFile, 0, this.dataOffset + 8); + msOut.Write(waveFile, this.ChannelCount * 2 * newStartSample, waveFile.Length - (this.dataOffset + 8 + (this.ChannelCount * 2 * newStartSample))); + + int cutted = (this.ChannelCount * 2 * newStartSample) - (this.dataOffset + 8); + + byte[] newLength = BitConverter.GetBytes((UInt32)msOut.Position); + byte[] dataLength = BitConverter.GetBytes(BitConverter.ToInt32(waveFile, this.dataOffset + 4) - cutted); + + msOut.Seek(4, SeekOrigin.Begin); + msOut.Write(newLength, 0, newLength.Length); + msOut.Seek(this.dataOffset + 4, SeekOrigin.Begin); + msOut.Write(dataLength, 0, dataLength.Length); + + msOut.Seek(0, SeekOrigin.Begin); + return msOut; + } + /// /// Closes the Wave file /// @@ -135,6 +175,13 @@ namespace WaveFile //Private Functions + private int GetFrameCount() + { + int dataLength = GetDataLength(); + + return (dataLength / (this.ChannelCount * 2)); + } + private int GetLoopStart() { if (smplOffset == -1) return 0; diff --git a/CustomizeMii/Wii.cs b/CustomizeMii/Wii.cs index acb172d..6b65b12 100644 --- a/CustomizeMii/Wii.cs +++ b/CustomizeMii/Wii.cs @@ -57,6 +57,21 @@ namespace Wii return big; } + /// + /// Returns the current UTC Unix Timestamp as a Byte Array + /// + /// + public static byte[] GetTimestamp() + { + DateTime dtNow = DateTime.UtcNow; + TimeSpan tsTimestamp = (dtNow - new DateTime(1970, 1, 1, 0, 0, 0)); + + int timestamp = (int)tsTimestamp.TotalSeconds; + ASCIIEncoding enc = new ASCIIEncoding(); + byte[] timestampBytes = enc.GetBytes("CMiiUT" + timestamp.ToString()); + return timestampBytes; + } + /// /// Creates a new Byte Array out of the given one /// from the given offset with the specified length @@ -1347,6 +1362,50 @@ namespace Wii return decryptedkey; } + + /// + /// Decodes the Timestamp in the Trailer, if available. + /// Returns null if no Timestamp was found. + /// + /// + /// + public static DateTime GetCreationTime(string trailer) + { + byte[] bTrailer = Tools.LoadFileToByteArray(trailer); + return GetCreationTime(bTrailer); + } + + /// + /// Decodes the Timestamp in the Trailer, if available. + /// Returns null if no Timestamp was found. + /// + /// + /// + public static DateTime GetCreationTime(byte[] trailer) + { + DateTime result = new DateTime(1970, 1, 1); + + if (trailer[0] == 'C' && + trailer[1] == 'M' && + trailer[2] == 'i' && + trailer[3] == 'i' && + trailer[4] == 'U' && + trailer[5] == 'T') + { + ASCIIEncoding enc = new ASCIIEncoding(); + string stringSeconds = enc.GetString(trailer, 6, 10); + int seconds = 0; + + if (int.TryParse(stringSeconds, out seconds)) + { + result = result.AddSeconds((double)seconds); + return result; + } + else return result; + } + + return result; + } } public class WadEdit @@ -2267,6 +2326,18 @@ namespace Wii return wadtmd; } + + /// + /// Changes the Title Key in the Tik + /// + /// + /// + public static byte[] ChangeTitleKey(byte[] tik) + { + byte[] newKey = new byte[] { 0x47, 0x6f, 0x74, 0x74, 0x61, 0x47, 0x65, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x42, 0x65, 0x65, 0x72 }; + Tools.InsertByteArray(tik, newKey, 447); + return tik; + } } public class WadUnpack @@ -2575,7 +2646,7 @@ namespace Wii /// Packs the contents in the given directory and creates the destination wad file /// /// - public static void PackWad(string contentdirectory, string destinationfile, bool includefooter) + public static void PackWad(string contentdirectory, string destinationfile) { if (contentdirectory[contentdirectory.Length - 1] != '\\') { contentdirectory = contentdirectory + "\\"; } @@ -2589,12 +2660,13 @@ namespace Wii string[] certfile = Directory.GetFiles(contentdirectory, "*.cert"); string[] tikfile = Directory.GetFiles(contentdirectory, "*.tik"); string[] tmdfile = Directory.GetFiles(contentdirectory, "*.tmd"); - string[] trailerfile = Directory.GetFiles(contentdirectory, "*.trailer"); byte[] cert = Tools.LoadFileToByteArray(certfile[0]); byte[] tik = Tools.LoadFileToByteArray(tikfile[0]); byte[] tmd = Tools.LoadFileToByteArray(tmdfile[0]); + tik = WadEdit.ChangeTitleKey(tik); + string[,] contents = WadInfo.GetContentInfo(tmd); FileStream wadstream = new FileStream(destinationfile, FileMode.Create); @@ -2638,23 +2710,20 @@ namespace Wii allcont += thiscont.Length; } - //Write Trailer, if exists and includefooter = true - int trailerlength = 0; - if (trailerfile.Length > 0 && includefooter == true) - { - byte[] trailer = Tools.LoadFileToByteArray(trailerfile[0]); - trailerlength = trailer.Length; - Array.Resize(ref trailer, Tools.AddPadding(trailer.Length)); - wadstream.Seek(Tools.AddPadding(contpos), SeekOrigin.Begin); - wadstream.Write(trailer, 0, trailer.Length); - } + //Write Footer Timestamp + byte[] footer = Tools.GetTimestamp(); + Array.Resize(ref footer, Tools.AddPadding(footer.Length, 16)); + + int footerLength = footer.Length; + wadstream.Seek(Tools.AddPadding(contpos), SeekOrigin.Begin); + wadstream.Write(footer, 0, footer.Length); //Write Header byte[] certsize = Tools.FileLengthToByteArray(cert.Length); byte[] tiksize = Tools.FileLengthToByteArray(tik.Length); byte[] tmdsize = Tools.FileLengthToByteArray(tmd.Length); byte[] allcontsize = Tools.FileLengthToByteArray(allcont); - byte[] trailersize = Tools.FileLengthToByteArray(trailerlength); + byte[] footersize = Tools.FileLengthToByteArray(footerLength); wadstream.Seek(0x00, SeekOrigin.Begin); wadstream.Write(wadheader, 0, wadheader.Length); @@ -2667,7 +2736,7 @@ namespace Wii wadstream.Seek(0x18, SeekOrigin.Begin); wadstream.Write(allcontsize, 0, allcontsize.Length); wadstream.Seek(0x1c, SeekOrigin.Begin); - wadstream.Write(trailersize, 0, trailersize.Length); + wadstream.Write(footersize, 0, footersize.Length); wadstream.Close(); } @@ -2699,6 +2768,8 @@ namespace Wii byte[] tik = Tools.LoadFileToByteArray(ticketdir + path2 + ".tik"); byte[] tmd = Tools.LoadFileToByteArray(contentdir + "title.tmd"); + tik = WadEdit.ChangeTitleKey(tik); + string[,] contents = WadInfo.GetContentInfo(tmd); FileStream wadstream = new FileStream(destinationfile, FileMode.Create); @@ -2758,12 +2829,20 @@ namespace Wii allcont += thiscont.Length; } + //Write Footer Timestamp + byte[] footer = Tools.GetTimestamp(); + Array.Resize(ref footer, Tools.AddPadding(footer.Length, 16)); + + int footerLength = footer.Length; + wadstream.Seek(Tools.AddPadding(contpos), SeekOrigin.Begin); + wadstream.Write(footer, 0, footer.Length); + //Write Header byte[] certsize = Tools.FileLengthToByteArray(cert.Length); byte[] tiksize = Tools.FileLengthToByteArray(tik.Length); byte[] tmdsize = Tools.FileLengthToByteArray(tmd.Length); byte[] allcontsize = Tools.FileLengthToByteArray(allcont); - byte[] trailersize = new byte[] { 0x00, 0x00, 0x00, 0x00 }; + byte[] footersize = Tools.FileLengthToByteArray(footerLength); wadstream.Seek(0x00, SeekOrigin.Begin); wadstream.Write(wadheader, 0, wadheader.Length); @@ -2776,7 +2855,7 @@ namespace Wii wadstream.Seek(0x18, SeekOrigin.Begin); wadstream.Write(allcontsize, 0, allcontsize.Length); wadstream.Seek(0x1c, SeekOrigin.Begin); - wadstream.Write(trailersize, 0, trailersize.Length); + wadstream.Write(footersize, 0, footersize.Length); wadstream.Close(); }