From e54e8eca2a0e38b4c7b9012e376c48f087663a2f Mon Sep 17 00:00:00 2001 From: CatmanFan Date: Sat, 13 Apr 2024 05:21:27 +0100 Subject: [PATCH] Migration --- FriishProduce/Database.xml | 657 ------------------ FriishProduce/FriishProduce.csproj | 3 +- FriishProduce/ProjectForm.Designer.cs | 40 +- FriishProduce/ProjectForm.cs | 326 +++++---- FriishProduce/ProjectForm.resx | 118 ++-- .../Properties/Resources.Designer.cs | 20 +- FriishProduce/Properties/Resources.resx | 6 +- FriishProduce/Subforms/About.cs | 2 +- FriishProduce/_classes/BannerHelper.cs | 97 +-- FriishProduce/_classes/BannerPreview.cs | 2 +- FriishProduce/_classes/Database.cs | 274 -------- FriishProduce/_classes/Modifiers/WiiVC.cs | 54 +- FriishProduce/_classes/Program/Database.cs | 140 ++++ FriishProduce/_classes/Program/Language.cs | 4 +- FriishProduce/database.json | 376 +++++++--- 15 files changed, 780 insertions(+), 1339 deletions(-) delete mode 100644 FriishProduce/Database.xml delete mode 100644 FriishProduce/_classes/Database.cs create mode 100644 FriishProduce/_classes/Program/Database.cs diff --git a/FriishProduce/Database.xml b/FriishProduce/Database.xml deleted file mode 100644 index 2aa5e205..00000000 --- a/FriishProduce/Database.xml +++ /dev/null @@ -1,657 +0,0 @@ - - - - - - - - - - - - - - - - FCWE - Super Mario Bros. 3 - Super Mario Bros. 3 - 0 - - - - FCWP - Super Mario Bros. 3 - Super Mario Bros. 3 - 0 - - - - FCWJ - Super Mario Bros. 3 - スーパーマリオブラザーズ3 - 0 - - - - FCWQ - Super Mario Bros. 3 - 슈퍼 마리오브라더스 3 - 0 - - - - FA8E - Kirby's Adventure - Kirby's Adventure - 0 - - - - FA8P - Kirby's Adventure - Kirby's Adventure - 0 - - - - FA8J - Hoshi no Kirby - Yume no Izumi no Monogatari - 星のカービィ 夢の泉の物語 - 0 - - - - FA8T - Kirby's Adventure - 별의 커비 꿈의 샘 이야기 - 0 - - - - FBNM - Ninja Gaiden - Ninja Gaiden - 0 - - - - - - - - - - - JBDE - Donkey Kong Country 2 - Diddy's Kong Quest - Donkey Kong Country 2 - 0 - - - - JBDP - Donkey Kong Country 2 - Diddy's Kong Quest - Donkey Kong Country 2 - 0 - - - - JBDJ - Super Donkey Kong 2 - Dixie & Diddy - スーパードンキーコング2 - 0 - - - - JBDT - Donkey Kong Country 2 - Diddy's Kong Quest - 동키콩 컨트리 2 - 0 - - - - JABL - Mario's Super Picross - Mario's Super Picross - 0 - - - - - - - - - - - - NAAE - Super Mario 64 - Super Mario 64 - 0 - - - - NAAP - Super Mario 64 - Super Mario 64 - 0 - - - - NAAJ - Super Mario 64 - スーパーマリオ64 - 0 - - - - NAFE - F-Zero X - F-Zero X - 0 - - - - NAFP - F-Zero X - F-Zero X - 0 - - - - NAFJ - F-Zero X - F-ZERO X - 0 - - - - NADE - Star Fox 64 - Star Fox 64 - 1 - - - - NADP - Lylat Wars - Lylat Wars - 1 - - - - NADJ - Star Fox 64 - スターフォックス64 - 1 - - - - NADT - Star Fox 64 - 스타폭스 64 - 3 - - - - NABE - Mario Kart 64 - Mario Kart 64 - 1 - - - - NABP - Mario Kart 64 - Mario Kart 64 - 1 - - - - NABJ - Mario Kart 64 - マリオカート64 - 1 - - - - NABT - Mario Kart 64 - 마리오 카트 64 - 3 - - - - NACE - Legend of Zelda, The - Ocarina of Time - The Legend of Zelda: Ocarina of Time - 1 - - - - NACP - Legend of Zelda, The - Ocarina of Time - The Legend of Zelda: Ocarina of Time - 1 - - - - NACJ - Zelda no Densetsu - Toki no Okarina - ゼルダの伝説 時のオカリナ - 1 - - - - NAJN - Sin & Punishment - Sin and Punishment - 2 - - - - NAJL - Sin & Punishment - Sin and Punishment - 2 - - - - NAJJ - Tsumi to Batsu - Hoshi no Keishousha - 罪と罰 〜地球の継承者〜 - 2 - - - - NAUE - Mario Golf - Mario Golf - 3 - - - - NAUP - Mario Golf - Mario Golf - 3 - - - - NAUJ - Mario Golf 64 - マリオゴルフ64 - 3 - - - - NAYE - Ogre Battle 64 - Person of Lordly Caliber - Ogre Battle 64: Person of Lordly Caliber - 3 - - - - NAYP - Ogre Battle 64 - Person of Lordly Caliber - Ogre Battle 64: Person of Lordly Caliber - 3 - - - - NAYJ - Ogre Battle 64 - Person of Lordly Caliber - オウガバトル64 Person of Lordly Caliber - 3 - - - - NA3E - Bomberman Hero - Bomberman Hero - 3 - - - - NA3P - Bomberman Hero - Bomberman Hero - 3 - - - - NA3J - Bomberman Hero - Millian-Oujo wo Sukue! - Bomberman Hero - ボンバーマンヒーロー ミリアン王女を救え! - 3 - - - - NAPJ - Custom Robo V2 - カスタムロボV2 - 3 - - - - - - - - - - - - - LAGE - Sonic The Hedgehog - Sonic the Hedgehog - 2 - - - - LAGP - Sonic The Hedgehog - Sonic the Hedgehog - 2 - - - - LAGJ - Sonic The Hedgehog - ソニック・ザ・ヘッジホッグ - 2 - - - - LADE - Phantasy Star - Phantasy Star - 3 - - - - LADP - Phantasy Star - Phantasy Star - 3 - - - - LADJ - Phantasy Star - ファンタシースター - 2 - - - - - - - - - - - MA6E - Streets of Rage 2 - Streets of Rage 2 - 2 - - - - MA6P - Streets of Rage 2 - Streets of Rage 2 - 2 - - - - MA6J - Bare Knuckle II - Shitou he no Requiem - ベア・ナックルII 死闘への鎮魂歌 - 2 - - - - MBAN - Pulseman - Pulseman - 3 - - - - MBAL - Pulseman - Pulseman - 3 - - - - MBAJ - Pulseman - パルスマン - 2 - - - - - - PAGN - Bomberman '94 - Bomberman '94 - 0 - - - - PAGL - Bomberman '94 - Bomberman '94 - 0 - - - - PAGJ - Bomberman '94 - ボンバーマン'94 - 0 - - - - PAAE - Bomberman '93 - Bomberman '93 - 0 - - - - PAAP - Bomberman '93 - Bomberman '93 - 0 - - - - PACE - Dungeon Explorer - Dungeon Explorer - 0 - - - - PACP - Dungeon Explorer - Dungeon Explorer - 0 - - - - PACJ - Dungeon Explorer - ダンジョン エクスプローラー - 0 - - - - PAEE - Super Star Soldier - Super Star Soldier - 0 - - - - PAEP - Super Star Soldier - Super Star Soldier - 0 - - - - PAEJ - Super Star Soldier - スーパースターソルジャー - 0 - - - - - - EAGE - King of Fighters '94, The - The King of Fighters '94 - 0 - - - - EAGP - King of Fighters '94, The - The King of Fighters '94 - 0 - - - - EAGJ - King of Fighters '94, The - ザ・キングオブファイターズ94 - 0 - - - - EAVE - King of Fighters '95, The - The King of Fighters '95 - 1 - - - - EAVP - King of Fighters '95, The - The King of Fighters '95 - 1 - - - - EAVJ - King of Fighters '95, The - ザ・キングオブファイターズ95 - 1 - - - - EAJE - Metal Slug - Metal Slug - 0 - - - - EAJP - Metal Slug - Metal Slug - 0 - - - - EAJJ - Metal Slug - メタルスラッグ - 0 - - - - - - C9YE - International Karate - International Karate - 0 - - - - C9YP - International Karate - International Karate - 0 - - - - - - XAGJ - Road Fighter - ロードファイター - 0 - - - - XAPJ - Metal Gear 2 - Solid Snake - メタルギア2 ソリッドスネーク - 1 - - - - - - WNAE - Flash Placeholder - Flash Placeholder - 0 - - - - WNAP - Flash Placeholder - Flash Placeholder - 0 - - - \ No newline at end of file diff --git a/FriishProduce/FriishProduce.csproj b/FriishProduce/FriishProduce.csproj index f8b79c19..83933c74 100644 --- a/FriishProduce/FriishProduce.csproj +++ b/FriishProduce/FriishProduce.csproj @@ -212,6 +212,7 @@ + @@ -300,7 +301,6 @@ - @@ -417,7 +417,6 @@ - diff --git a/FriishProduce/ProjectForm.Designer.cs b/FriishProduce/ProjectForm.Designer.cs index 5b77eca8..f9a8be6a 100644 --- a/FriishProduce/ProjectForm.Designer.cs +++ b/FriishProduce/ProjectForm.Designer.cs @@ -47,6 +47,8 @@ private void InitializeComponent() this.label3 = new System.Windows.Forms.Label(); this.InjectorsList = new System.Windows.Forms.ComboBox(); this.button1 = new System.Windows.Forms.Button(); + this.COPanel_VC = new System.Windows.Forms.Panel(); + this.CustomManual = new System.Windows.Forms.CheckBox(); this.COPanel_Forwarder = new System.Windows.Forms.Panel(); this.groupBox8 = new System.Windows.Forms.GroupBox(); this.FStorage_SD = new System.Windows.Forms.RadioButton(); @@ -54,8 +56,6 @@ private void InitializeComponent() this.groupBox9 = new System.Windows.Forms.GroupBox(); this.toggleSwitchL1 = new System.Windows.Forms.Label(); this.toggleSwitch1 = new JCS.ToggleSwitch(); - this.COPanel_VC = new System.Windows.Forms.Panel(); - this.CustomManual = new System.Windows.Forms.CheckBox(); this.label11 = new System.Windows.Forms.Label(); this.Patch = new System.Windows.Forms.CheckBox(); this.groupBox4 = new System.Windows.Forms.GroupBox(); @@ -94,10 +94,10 @@ private void InitializeComponent() this.groupBox6.SuspendLayout(); this.groupBox7.SuspendLayout(); this.groupBox3.SuspendLayout(); + this.COPanel_VC.SuspendLayout(); this.COPanel_Forwarder.SuspendLayout(); this.groupBox8.SuspendLayout(); this.groupBox9.SuspendLayout(); - this.COPanel_VC.SuspendLayout(); this.groupBox4.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.Random)).BeginInit(); this.groupBox1.SuspendLayout(); @@ -209,8 +209,8 @@ private void InitializeComponent() this.groupBox3.Controls.Add(this.label3); this.groupBox3.Controls.Add(this.InjectorsList); this.groupBox3.Controls.Add(this.button1); - this.groupBox3.Controls.Add(this.COPanel_Forwarder); this.groupBox3.Controls.Add(this.COPanel_VC); + this.groupBox3.Controls.Add(this.COPanel_Forwarder); resources.ApplyResources(this.groupBox3, "groupBox3"); this.groupBox3.Name = "groupBox3"; this.groupBox3.TabStop = false; @@ -241,6 +241,20 @@ private void InitializeComponent() this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.OpenInjectorOptions); // + // COPanel_VC + // + this.COPanel_VC.Controls.Add(this.CustomManual); + resources.ApplyResources(this.COPanel_VC, "COPanel_VC"); + this.COPanel_VC.Name = "COPanel_VC"; + // + // CustomManual + // + resources.ApplyResources(this.CustomManual, "CustomManual"); + this.CustomManual.Name = "CustomManual"; + this.CustomManual.Tag = "import_manual"; + this.CustomManual.UseVisualStyleBackColor = true; + this.CustomManual.CheckedChanged += new System.EventHandler(this.CustomManual_CheckedChanged); + // // COPanel_Forwarder // this.COPanel_Forwarder.Controls.Add(this.groupBox8); @@ -296,20 +310,6 @@ private void InitializeComponent() this.toggleSwitch1.Style = JCS.ToggleSwitch.ToggleSwitchStyle.IOS5; this.toggleSwitch1.CheckedChanged += new JCS.ToggleSwitch.CheckedChangedDelegate(this.ToggleSwitchChanged); // - // COPanel_VC - // - this.COPanel_VC.Controls.Add(this.CustomManual); - resources.ApplyResources(this.COPanel_VC, "COPanel_VC"); - this.COPanel_VC.Name = "COPanel_VC"; - // - // CustomManual - // - resources.ApplyResources(this.CustomManual, "CustomManual"); - this.CustomManual.Name = "CustomManual"; - this.CustomManual.Tag = "import_manual"; - this.CustomManual.UseVisualStyleBackColor = true; - this.CustomManual.CheckedChanged += new System.EventHandler(this.CustomManual_CheckedChanged); - // // label11 // resources.ApplyResources(this.label11, "label11"); @@ -630,13 +630,13 @@ private void InitializeComponent() this.groupBox7.PerformLayout(); this.groupBox3.ResumeLayout(false); this.groupBox3.PerformLayout(); + this.COPanel_VC.ResumeLayout(false); + this.COPanel_VC.PerformLayout(); this.COPanel_Forwarder.ResumeLayout(false); this.groupBox8.ResumeLayout(false); this.groupBox8.PerformLayout(); this.groupBox9.ResumeLayout(false); this.groupBox9.PerformLayout(); - this.COPanel_VC.ResumeLayout(false); - this.COPanel_VC.PerformLayout(); this.groupBox4.ResumeLayout(false); this.groupBox4.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.Random)).EndInit(); diff --git a/FriishProduce/ProjectForm.cs b/FriishProduce/ProjectForm.cs index 6eb56896..de148e93 100644 --- a/FriishProduce/ProjectForm.cs +++ b/FriishProduce/ProjectForm.cs @@ -42,8 +42,7 @@ public bool ReadyToExport protected string PatchFile { get; set; } protected string Manual { get; set; } protected LibRetroDB LibRetro { get; set; } - protected DatabaseEntry[] Database { get; set; } - protected IDictionary CurrentBase { get; set; } + protected Database Database { get; set; } protected ImageHelper Img { get; set; } protected Creator Creator { get; set; } @@ -62,6 +61,7 @@ public bool ReadyToExport private ProjectType ParentProject { get; set; } public bool ROMLoaded { get => ROM?.Path != null; } private bool FormEnabled { get => groupBox1.Enabled && groupBox2.Enabled; } + private bool isVCMode { get => InjectorsList.SelectedItem?.ToString().ToLower() == Program.Lang.String("vc").ToLower(); } // ----------------------------------- @@ -162,34 +162,43 @@ public void RefreshForm() } #endregion - if (CurrentBase != null) - { - for (int i = 0; i < CurrentBase.Count; i++) + if (Base.SelectedIndex >= 0) + for (int i = 0; i < Database.Entries[Base.SelectedIndex].Regions.Count; i++) { - switch (CurrentBase.ElementAt(i).Key.ToString().ToUpper()[3]) + switch (Database.Entries[Base.SelectedIndex].Regions[i]) { default: - case 'E': - case 'N': - BaseRegionList.Items[i].Text = Program.Lang.String("region_u"); + case 0: + BaseRegionList.Items[i].Text = Program.Lang.String("region_j"); break; - case 'P': - case 'L': - case 'M': - BaseRegionList.Items[i].Text = Program.Lang.String("region_e"); + case 1: + case 2: + BaseRegionList.Items[i].Text = Program.Lang.String("region_u"); break; - case 'J': - BaseRegionList.Items[i].Text = Program.Lang.String("region_j"); + case 3: + case 4: + case 5: + BaseRegionList.Items[i].Text = Program.Lang.String("region_e"); break; - case 'Q': - case 'T': + case 6: + case 7: BaseRegionList.Items[i].Text = Program.Lang.String("region_k"); break; } } + + + for (int i = 0; i < Base.Items.Count; i++) + { + var title = Database.Entries[i].Regions.Contains(0) && Program.Lang.Current.StartsWith("ja") ? Database.Entries[i].Titles[0] + : Database.Entries[i].Regions.Contains(0) && Program.Lang.Current.StartsWith("ko") ? Database.Entries[i].Titles[Database.Entries[i].Titles.Count - 1] + : Database.Entries[i].Regions.Contains(0) && Database.Entries[i].Regions.Count > 1 ? Database.Entries[i].Titles[1] + : Database.Entries[i].Titles[0]; + + Base.Items[i] = title; } // Injection methods list @@ -257,6 +266,8 @@ public void RefreshForm() public ProjectForm(Console c, string ROMpath = null) { Console = c; + Database = new Database(Console); + InitializeComponent(); if (ROMpath != null) @@ -269,7 +280,9 @@ public ProjectForm(Console c, string ROMpath = null) public ProjectForm(ProjectType p) { Console = p.Console; + Database = new Database(Console); ParentProject = p; + InitializeComponent(); } @@ -396,6 +409,7 @@ private void Form_Shown(object sender, EventArgs e) FStorage_USB.Checked = Options.FORWARDER.Default.root_storage_device.ToLower().Contains("usb"); FStorage_SD.Checked = !FStorage_USB.Checked; toggleSwitch1.Checked = Options.FORWARDER.Default.nand_loader.ToLower().Contains("vwii"); + CustomManual.Enabled = Console != Console.NEO && Console != Console.PCE; Tag = null; ExportCheck.Invoke(this, EventArgs.Empty); @@ -427,7 +441,7 @@ protected virtual void CheckExport() public bool[] CheckToolStripButtons() => new bool[] { Console != Console.Flash && (ROM?.Bytes != null || !string.IsNullOrWhiteSpace(ROM?.Path)), // LibRetro - Console != Console.Flash, // Browse manual + Console != Console.Flash && isVCMode, // Browse manual }; protected virtual void SetROMDataText() @@ -656,19 +670,18 @@ public bool LoadWAD(string path) return false; } - for (int x = 0; x < Database.Length; x++) - if (Database[x].TitleID.ToUpper() == Reader.UpperTitleID.ToUpper()) - { - WADPath = path; - - CurrentBase.Clear(); - CurrentBase.Add(Database[x].TitleID, Database[x].DisplayName); - baseName.Text = Database[x].DisplayName; - baseID.Text = Database[x].TitleID; - UpdateBaseGeneral(0); - Reader.Dispose(); - return true; - } + foreach (var entry in Database.Entries) + for (int i = 0; i < entry.Regions.Count; i++) + if (entry.GetUpperID(i) == Reader.UpperTitleID.ToUpper()) + { + WADPath = path; + + baseName.Text = entry.Titles[i]; + baseID.Text = entry.GetUpperID(i); + UpdateBaseGeneral(0); + Reader.Dispose(); + return true; + } Reader.Dispose(); System.Media.SystemSounds.Beep.Play(); @@ -891,8 +904,9 @@ public bool SaveToWAD() // Get WAD data // ******* if (WADPath != null) OutWAD = WAD.Load(WADPath); - else for (int x = 0; x < Database.Length; x++) - if (Database[x].TitleID.ToUpper() == baseID.Text.ToUpper()) OutWAD = Database[x].Load(); + else foreach (var entry in Database.Entries) + for (int i = 0; i < entry.Regions.Count; i++) + if (entry.GetUpperID(i) == baseID.Text.ToUpper()) OutWAD = entry.GetWAD(i); switch (Console) { @@ -904,7 +918,7 @@ public bool SaveToWAD() case Console.PCE: case Console.NEO: case Console.MSX: - if (IsVCMode()) + if (isVCMode) WiiVCInject(); else ForwarderCreator(); @@ -1113,16 +1127,14 @@ private void OpenInjectorOptions(object sender, EventArgs e) #region Base WAD Management/Visual private void AddBases() { - Database = DatabaseHelper.Get(Console) ?? DatabaseHelper.Get(Console.Flash); - string ID = null; - - for (int x = 0; x < Database.Length; x++) + foreach (var entry in Database.Entries) { - if (Database[x].TitleID.Substring(0, 3) != ID) - { - Base.Items.Add(Database[x].DisplayName); - ID = Database[x].TitleID.Substring(0, 3); - } + var title = entry.Regions.Contains(0) && Program.Lang.Current.StartsWith("ja") ? entry.Titles[0] + : entry.Regions.Contains(0) && Program.Lang.Current.StartsWith("ko") ? entry.Titles[entry.Titles.Count - 1] + : entry.Regions.Contains(0) && entry.Regions.Count > 1 ? entry.Titles[1] + : entry.Titles[0]; + + Base.Items.Add(title); } if (Base.Items.Count > 0) { Base.SelectedIndex = 0; } @@ -1140,101 +1152,116 @@ private void Base_SelectedIndexChanged(object sender, EventArgs e) if (DesignMode) return; // ---------------------------- - // Reset currently-selected base info - // ******** - CurrentBase = new Dictionary(); - BaseRegionList.Items.Clear(); - - // Add base native names to temporary list - // ******** - var tempList = new List(); - var tempIDs = new List(); - for (int x = 0; x < Database.Length; x++) tempList.Add(Database[x].DisplayName); - for (int x = 0; x < Database.Length; x++) tempIDs.Add(Database[x].TitleID.Substring(0, 3)); - - int start = tempList.IndexOf(Base.SelectedItem.ToString()); - int end = start == Database.Length - 1 ? Database.Length : -1; - - for (int x = start; x < Database.Length; x++) + var regions = new List(); + for (int i = 0; i < Database.Entries[Base.SelectedIndex].Regions.Count; i++) { - if (Database[x].TitleID.Substring(0, 3) != Database[start].TitleID.Substring(0, 3) && end == -1) - end = x; - } - - if (end == -1) end = Database.Length; - - // Add regions to WAD region context list - // ******** - for (int x = start; x < end; x++) - { - // Add region of entry to context list - // ******** - switch (Database[x].Region()) + switch (Database.Entries[Base.SelectedIndex].Regions[i]) { case 0: - BaseRegionList.Items.Add(Program.Lang.String("region_u"), null, WADRegionList_Click); + regions.Add(Program.Lang.String("region_j")); break; case 1: case 2: - BaseRegionList.Items.Add(Program.Lang.String("region_e"), null, WADRegionList_Click); + regions.Add(Program.Lang.String("region_u")); break; case 3: - BaseRegionList.Items.Add(Program.Lang.String("region_j"), null, WADRegionList_Click); - break; - case 4: case 5: - BaseRegionList.Items.Add(Program.Lang.String("region_k"), null, WADRegionList_Click); + regions.Add(Program.Lang.String("region_e")); + break; + + case 6: + case 7: + regions.Add(Program.Lang.String("region_k")); break; default: break; } - - CurrentBase.Add(Database[x].TitleID, Database[x].DisplayName); } // Check if language is set to Japanese or Korean // If so, make Japan/Korea region item the first in the WAD region context list // ******** - string langCode = Program.Lang.Current; - if (langCode == "ja" || langCode == "ko") + var selected = regions.IndexOf(Program.Lang.String("region_u")); + + var altRegions = new Dictionary() { - string target = langCode == "ja" ? Program.Lang.String("region_j") : Program.Lang.String("region_k"); + { "ja", 0 }, + { "ko", 1 }, + { "fr", 2 }, + { "de", 2 }, + { "nl", 2 }, + { "it", 2 }, + { "pl", 2 }, + { "ru", 2 }, + { "uk", 2 }, + { "tr", 2 }, + { "hu", 2 }, + { "ca", 2 }, + { "eu", 2 }, + { "gl", 2 }, + { "ast", 2 }, + { "no", 2 }, + { "sv", 2 }, + { "fi", 2 }, + { "-GB", 2 }, + { "-UK", 2 }, + { "-ES", 2 }, + { "-PT", 2 }, + { "-RU", 2 }, + { "-IN", 2 }, + { "-ZA", 2 }, + { "-CA", 3 }, + { "-US", 3 }, + { "-MX", 3 }, + { "-BR", 3 }, + }; + foreach (var item in altRegions) if (Program.Lang.Current.ToLower().StartsWith(item.Key) || (item.Key.Contains("-") && Program.Lang.Current.ToLower().EndsWith(item.Key))) + selected = regions.IndexOf(item.Value == 0 ? Program.Lang.String("region_j") : item.Value == 1 ? Program.Lang.String("region_k") : item.Value == 2 ? Program.Lang.String("region_e") : Program.Lang.String("region_u")); - for (int i = 0; i < BaseRegionList.Items.Count; i++) - if ((BaseRegionList.Items[i] as ToolStripMenuItem).Text == target) - { - // Swap first element of context list with Japan/Korea - // ******** - var tempDict = new Dictionary { { BaseRegionList.Items[i].Text, null } }; + if (selected == -1) selected = 0; - for (int j = 0; j < CurrentBase.Count; j++) - try { tempDict.Add(BaseRegionList.Items[j].Text, null); } catch { } + // Reset currently-selected base info + // ******** + BaseRegionList.Items.Clear(); - for (int x = 0; x < BaseRegionList.Items.Count; x++) - { - var item = BaseRegionList.Items[x] as ToolStripMenuItem; - item.Text = tempDict.ElementAt(x).Key; - } + // Add regions to WAD region context list + // ******** + for (int i = 0; i < Database.Entries[Base.SelectedIndex].Regions.Count; i++) + { + switch (Database.Entries[Base.SelectedIndex].Regions[i]) + { + case 0: + BaseRegionList.Items.Add(Program.Lang.String("region_j"), null, WADRegionList_Click); + break; + + case 1: + case 2: + BaseRegionList.Items.Add(Program.Lang.String("region_u"), null, WADRegionList_Click); + break; - // Likewise do the same for the CurrentBase dictionary - // ******** - tempDict = new Dictionary { { CurrentBase.ElementAt(i).Key, CurrentBase.ElementAt(i).Value } }; + case 3: + case 4: + case 5: + BaseRegionList.Items.Add(Program.Lang.String("region_e"), null, WADRegionList_Click); + break; - for (int j = 0; j < CurrentBase.Count; j++) - if (CurrentBase.ElementAt(j).Key != tempDict.ElementAt(0).Key) - tempDict.Add(CurrentBase.ElementAt(j).Key, CurrentBase.ElementAt(j).Value); - CurrentBase = tempDict; - } + case 6: + case 7: + BaseRegionList.Items.Add(Program.Lang.String("region_k"), null, WADRegionList_Click); + break; + + default: + break; + } } // Final visual updates // ******** - (BaseRegionList.Items[0] as ToolStripMenuItem).Checked = true; - UpdateBaseForm(0); + UpdateBaseForm(selected); BaseRegion.Cursor = BaseRegionList.Items.Count == 1 ? Cursors.Default : Cursors.Hand; } @@ -1246,68 +1273,65 @@ private void WADRegion_Click(object sender, EventArgs e) private void WADRegionList_Click(object sender, EventArgs e) { - foreach (ToolStripMenuItem item in BaseRegionList.Items.OfType()) - item.Checked = false; - string targetRegion = (sender as ToolStripMenuItem).Text; for (int i = 0; i < BaseRegionList.Items.Count; i++) { - var item = BaseRegionList.Items[i] as ToolStripMenuItem; - if (item.Text == targetRegion) + if ((BaseRegionList.Items[i] as ToolStripMenuItem).Text == targetRegion) { - baseID.Text = CurrentBase.ElementAt(i).Key; - item.Checked = true; - UpdateBaseForm(); + UpdateBaseForm(i); CheckExport(); return; } } - } private void UpdateBaseForm(int index = -1) { if (index == -1) { - for (index = 0; index < CurrentBase.Count; index++) - if (CurrentBase.ElementAt(index).Key[3] == baseID.Text[3]) + for (index = 0; index < Database.Entries[Base.SelectedIndex].Regions.Count; index++) + if (Database.Entries[Base.SelectedIndex].GetUpperID(index)[3] == baseID.Text[3]) goto Set; return; } - Set: + Set: // Native name & Title ID // ******** - baseName.Text = CurrentBase.ElementAt(index).Value; - baseID.Text = CurrentBase.ElementAt(index).Key; + baseName.Text = Database.Entries[Base.SelectedIndex].Titles[index]; + baseID.Text = Database.Entries[Base.SelectedIndex].GetUpperID(index); + + foreach (ToolStripMenuItem item in BaseRegionList.Items.OfType()) + item.Checked = false; + (BaseRegionList.Items[index] as ToolStripMenuItem).Checked = true; // Flag // ******** - switch (CurrentBase.ElementAt(index).Key[3]) + switch (Database.Entries[Base.SelectedIndex].Regions[index]) { default: - case 'E': - case 'N': + case 0: + BaseRegion.Image = Properties.Resources.flag_jp; + break; + + case 1: + case 2: BaseRegion.Image = Properties.Resources.flag_us; break; - case 'P': + case 3: BaseRegion.Image = (int)Console <= 2 ? Properties.Resources.flag_eu50 : Properties.Resources.flag_eu; break; - case 'L': - case 'M': + case 4: + case 5: BaseRegion.Image = (int)Console <= 2 ? Properties.Resources.flag_eu60 : Properties.Resources.flag_eu; break; - case 'J': - BaseRegion.Image = Properties.Resources.flag_jp; - break; - - case 'Q': - case 'T': + case 6: + case 7: BaseRegion.Image = Properties.Resources.flag_kr; break; } @@ -1321,13 +1345,9 @@ private void UpdateBaseGeneral(int index) // Korean WADs use different encoding format & using two lines or going over max limit cause visual bugs // ******** - Creator.OrigRegion = CurrentBase.ElementAt(index).Key[3] == 'Q' - || CurrentBase.ElementAt(index).Key[3] == 'T' - || CurrentBase.ElementAt(index).Key[3] == 'K' ? Creator.RegionType.Korea - : CurrentBase.ElementAt(index).Key[3] == 'J' ? Creator.RegionType.Japan - : CurrentBase.ElementAt(index).Key[3] == 'P' - || CurrentBase.ElementAt(index).Key[3] == 'L' - || CurrentBase.ElementAt(index).Key[3] == 'M' ? Creator.RegionType.Europe + Creator.OrigRegion = Database.Entries[Base.SelectedIndex].Regions[index] >= 6 ? Creator.RegionType.Korea + : Database.Entries[Base.SelectedIndex].Regions[index] == 0 ? Creator.RegionType.Japan + : Database.Entries[Base.SelectedIndex].Regions[index] >= 3 && Database.Entries[Base.SelectedIndex].Regions[index] <= 5 ? Creator.RegionType.Europe : Creator.RegionType.Universal; // Changing SaveDataTitle max length & clearing text field when needed @@ -1371,14 +1391,18 @@ private void UpdateBaseGeneral(int index) pictureBox1.Image = Preview.Banner(Console, BannerTitle.Text, (int)ReleaseYear.Value, (int)Players.Value, Img?.VCPic, (int)Creator.OrigRegion); } - private int EmuVer() + private int emuVer { - if (Database != null) - foreach (var Entry in Database) - if (Entry.TitleID.ToUpper() == baseID.Text.ToUpper()) - return Entry.Emulator; + get + { + if (Database != null) + foreach (var entry in Database.Entries) + for (int i = 0; i < entry.Regions.Count; i++) + if (entry.GetUpperID(i) == baseID.Text.ToUpper()) + return entry.EmuRevs[i]; - return 0; + return 0; + } } private void ResetContentOptions() @@ -1388,7 +1412,7 @@ private void ResetContentOptions() bool ShowSaveData = false; CO = null; - if (IsVCMode()) + if (isVCMode) { COPanel_VC.Show(); ShowSaveData = true; @@ -1463,12 +1487,12 @@ private void UpdateBaseConsole() break; case Console.N64: - if (IsVCMode()) CO.EmuType = Creator.OrigRegion == Creator.RegionType.Korea ? 3 : EmuVer(); + if (isVCMode) CO.EmuType = Creator.OrigRegion == Creator.RegionType.Korea ? 3 : emuVer; break; case Console.SMS: case Console.SMD: - CO.EmuType = EmuVer(); + CO.EmuType = emuVer; break; case Console.PCE: @@ -1524,7 +1548,7 @@ private void ChannelTitle_Locale_CheckedChanged(object sender, EventArgs e) private void CustomManual_CheckedChanged(object sender, EventArgs e) { - if (CustomManual.Checked) + if (CustomManual.Checked && CustomManual.Enabled) { if (!Properties.Settings.Default.DoNotShow_000) MessageBox.Show((sender as Control).Text, Program.Lang.Msg(6), 0); @@ -1546,7 +1570,7 @@ private void CustomManual_CheckedChanged(object sender, EventArgs e) } } - else if (!CustomManual.Checked && Manual != null) + else if (!CustomManual.Checked && Manual != null && CustomManual.Enabled) { LoadManual(null); CheckExport(); @@ -1582,8 +1606,6 @@ private void Patch_CheckedChanged(object sender, EventArgs e) } } - private bool IsVCMode() => InjectorsList.SelectedItem.ToString().ToLower() == Program.Lang.String("vc").ToLower(); - private void InjectorsList_SelectedIndexChanged(object sender, EventArgs e) { ResetContentOptions(); diff --git a/FriishProduce/ProjectForm.resx b/FriishProduce/ProjectForm.resx index 896ec51b..802049b9 100644 --- a/FriishProduce/ProjectForm.resx +++ b/FriishProduce/ProjectForm.resx @@ -504,6 +504,63 @@ 2 + + True + + + False + + + NoControl + + + 0, 1 + + + 94, 17 + + + 6 + + + import_manual + + + CustomManual + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + COPanel_VC + + + 0 + + + 12, 67 + + + 376, 20 + + + 42 + + + False + + + COPanel_VC + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBox3 + + + 3 + True @@ -676,63 +733,6 @@ groupBox3 - 3 - - - True - - - False - - - NoControl - - - 0, 1 - - - 94, 17 - - - 6 - - - import_manual - - - CustomManual - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - COPanel_VC - - - 0 - - - 12, 67 - - - 376, 20 - - - 42 - - - False - - - COPanel_VC - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - groupBox3 - - 4 @@ -772,7 +772,7 @@ NoControl - 26, 81 + 28, 80 31, 13 @@ -1699,7 +1699,7 @@ NoControl - 978, 261 + 977, 261 130, 96 diff --git a/FriishProduce/Properties/Resources.Designer.cs b/FriishProduce/Properties/Resources.Designer.cs index 91b492d9..4687ff95 100644 --- a/FriishProduce/Properties/Resources.Designer.cs +++ b/FriishProduce/Properties/Resources.Designer.cs @@ -191,20 +191,12 @@ public static System.Drawing.Bitmap cross { } /// - /// Looks up a localized string similar to <Databases> - /// <!-- INFORMATION ON ADDING NEW DATABASE ENTRIES --> - /// - /// <!-- <Name> = WAD Name as found on MarioCube database (game title ONLY, do not include any parentheses!) --> - /// <!-- <DisplayName> = Game's native title in English, Japanese or Korean --> - /// <!-- <Emulator> = determines the emulator type, if it exists. This can either be one that uses a compressed ROM, or a different frontend. --> - /// <!-- Settings are explained in each console database --> - /// - /// <Database Type="NES"> - /// <!-- [Emulator type [rest of string was truncated]";. - /// - public static string Database { - get { - return ResourceManager.GetString("Database", resourceCulture); + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] Database { + get { + object obj = ResourceManager.GetObject("Database", resourceCulture); + return ((byte[])(obj)); } } diff --git a/FriishProduce/Properties/Resources.resx b/FriishProduce/Properties/Resources.resx index aa8c002c..549355c9 100644 --- a/FriishProduce/Properties/Resources.resx +++ b/FriishProduce/Properties/Resources.resx @@ -265,9 +265,6 @@ ..\Resources\icons\consoles\sega master system.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\database.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - ..\Resources\icons\box-label_large.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -334,4 +331,7 @@ ..\Resources\icons\folder-horizontal-open.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\database.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/FriishProduce/Subforms/About.cs b/FriishProduce/Subforms/About.cs index ac53ac51..f27960d5 100644 --- a/FriishProduce/Subforms/About.cs +++ b/FriishProduce/Subforms/About.cs @@ -9,7 +9,7 @@ partial class About : Form public About() { InitializeComponent(); - this.Text = string.Format(Program.Lang.String("about"), Program.Lang.ApplicationTitle); + this.Text = string.Format(Program.Lang.String("about_app"), Program.Lang.ApplicationTitle); this.labelProductName.Text = AssemblyProduct; this.labelVersion.Text = Updater.GetCurrentVersion(); this.labelCopyright.Text = AssemblyCopyright; diff --git a/FriishProduce/_classes/BannerHelper.cs b/FriishProduce/_classes/BannerHelper.cs index 56f43919..3330b790 100644 --- a/FriishProduce/_classes/BannerHelper.cs +++ b/FriishProduce/_classes/BannerHelper.cs @@ -309,51 +309,62 @@ public static void ExportBanner(string tID, Console c) { if (File.Exists(Paths.Banners + tID.ToUpper() + ".bnr")) return; - WAD w = DatabaseHelper.Get(tID).Load(); - (U8, U8) Banner = Get(w); - Banner.Item2.Dispose(); - - // VCBrlyt and create temporary .brlyt file - // **************** - string BRLYTPath = Path.Combine(Paths.WorkingFolder, "banner.brlyt"); - File.WriteAllBytes(BRLYTPath, Banner.Item1.Data[Banner.Item1.GetNodeIndex("banner.brlyt")]); - - if (tID.ToUpper().EndsWith("Q") || tID.ToUpper().EndsWith("T")) - { - Utils.Run - ( - "vcbrlyt\\vcbrlyt.exe", - $"..\\..\\temp\\banner.brlyt -H_T_VCTitle_KOR \"VC................................................................................................................................\"" - ); - } - else - { - Utils.Run - ( - "vcbrlyt\\vcbrlyt.exe", - $"..\\..\\temp\\banner.brlyt -Title \"VC................................................................................................................................\" -YEAR VCVC -Play 4" - ); - } - - byte[] BRLYT = File.ReadAllBytes(BRLYTPath); - File.Delete(BRLYTPath); - - // Check if modified - // **************** - if (BRLYT == Banner.Item1.Data[Banner.Item1.GetNodeIndex("banner.brlyt")]) + var d = new Database(c); + foreach (var entry in d.Entries) { - Banner.Item1.Dispose(); - return; + for (int i = 0; i < entry.Regions.Count; i++) + { + if (entry.GetUpperID(i).ToUpper() == tID.ToUpper()) + { + using (WAD w = entry.GetWAD(i)) + { + (U8, U8) Banner = Get(w); + Banner.Item2.Dispose(); + + // VCBrlyt and create temporary .brlyt file + // **************** + string BRLYTPath = Path.Combine(Paths.WorkingFolder, "banner.brlyt"); + File.WriteAllBytes(BRLYTPath, Banner.Item1.Data[Banner.Item1.GetNodeIndex("banner.brlyt")]); + + if (tID.ToUpper().EndsWith("Q") || tID.ToUpper().EndsWith("T")) + { + Utils.Run + ( + "vcbrlyt\\vcbrlyt.exe", + $"..\\..\\temp\\banner.brlyt -H_T_VCTitle_KOR \"VC................................................................................................................................\"" + ); + } + else + { + Utils.Run + ( + "vcbrlyt\\vcbrlyt.exe", + $"..\\..\\temp\\banner.brlyt -Title \"VC................................................................................................................................\" -YEAR VCVC -Play 4" + ); + } + + byte[] BRLYT = File.ReadAllBytes(BRLYTPath); + File.Delete(BRLYTPath); + + // Check if modified + // **************** + if (BRLYT == Banner.Item1.Data[Banner.Item1.GetNodeIndex("banner.brlyt")]) + { + Banner.Item1.Dispose(); + return; + } + + // Replace + // **************** + Banner.Item1.ReplaceFile(Banner.Item1.GetNodeIndex("banner.brlyt"), BRLYT); + + if (!Directory.Exists(Paths.Banners)) Directory.CreateDirectory(Paths.Banners); + File.WriteAllBytes(Paths.Banners + tID.ToUpper() + ".bnr", Banner.Item1.ToByteArray()); + Banner.Item1.Dispose(); + } + } + } } - - // Replace - // **************** - Banner.Item1.ReplaceFile(Banner.Item1.GetNodeIndex("banner.brlyt"), BRLYT); - - if (!Directory.Exists(Paths.Banners)) Directory.CreateDirectory(Paths.Banners); - File.WriteAllBytes(Paths.Banners + tID.ToUpper() + ".bnr", Banner.Item1.ToByteArray()); - Banner.Item1.Dispose(); - w.Dispose(); } catch (Exception ex) { diff --git a/FriishProduce/_classes/BannerPreview.cs b/FriishProduce/_classes/BannerPreview.cs index c93b99cf..5687b6fa 100644 --- a/FriishProduce/_classes/BannerPreview.cs +++ b/FriishProduce/_classes/BannerPreview.cs @@ -349,7 +349,7 @@ public static Bitmap Banner(Console console, string text, int year, int players, // Players // ******** g.DrawString( - string.Format(numPlayers, players), + string.Format(numPlayers, $"{1}{(players <= 1 ? null : "-" + players)}").Replace("-", lang == 1 ? "~" : "-"), new Font(Font(), (float)9.25), new SolidBrush(leftTextColor), 10, diff --git a/FriishProduce/_classes/Database.cs b/FriishProduce/_classes/Database.cs deleted file mode 100644 index 9cb3a555..00000000 --- a/FriishProduce/_classes/Database.cs +++ /dev/null @@ -1,274 +0,0 @@ -using libWiiSharp; -using System; -using System.IO; -using System.Text; - -using System.Xml; -using System.Xml.Serialization; - -namespace FriishProduce -{ - public static class XmlHelper - { - /// - /// Serializes an object to an XML string, using the specified namespaces. - /// - public static string ToXml(object obj, XmlSerializerNamespaces ns) - { - Type T = obj.GetType(); - - var xs = new XmlSerializer(T, new XmlRootAttribute("Databases")); - var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = true, OmitXmlDeclaration = true }; - - var sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, ws)) - { - xs.Serialize(writer, obj, ns); - } - return sb.ToString(); - } - - /// - /// Serializes an object to an XML string. - /// - public static string ToXml(object obj) - { - var ns = new XmlSerializerNamespaces(); - ns.Add("", ""); - return ToXml(obj, ns); - } - - /// - /// Deserializes an object from an XML string. - /// - public static T FromXml(string xml) - { - XmlSerializer xs = new XmlSerializer(typeof(T), new XmlRootAttribute("Databases")); - using (StringReader sr = new StringReader(xml)) - { - return (T)xs.Deserialize(sr); - } - } - - /// - /// Deserializes an object from an XML file. - /// - public static T FromXmlFile(string filePath) - { - StreamReader sr = new StreamReader(filePath); - try - { - var result = FromXml(sr.ReadToEnd()); - return result; - } - catch (Exception e) - { - throw new Exception("There was an error attempting to read the file " + filePath + "\n\n" + e.InnerException.Message); - } - finally - { - sr.Close(); - } - } - } - - [Serializable, XmlRoot("Databases", IsNullable = false)] - public class Database - { - [XmlAttribute] - public Console Type { get; set; } - - [XmlElement("Entry")] - public DatabaseEntry[] Entries { get; set; } - } - - [Serializable] - public class DatabaseEntry - { - [XmlElement("TID")] - public string TitleID { get; set; } - - [XmlElement("Name")] - public string Name { get; set; } // Name on MarioCube - - [XmlElement("DisplayName")] - public string DisplayName { get; set; } // Name in specific language to be displayed on GUI - - [XmlElement("Emulator")] - public int Emulator { get; set; } // Revision used by the WAD's emulator, if one exists - - // SEGA - // **************** - // NOTE FROM THE AUTHOR: Only Revision 2 and Revision 3 SEGA WADs are accepted currently, because CCF modification does not work with Revision 1 WADs (such as Comix Zone). - // They also have more customizable options anyway, such as brightness (which can be adjusted to 100%), sound, 6-button, etc. - // **************** - - public WAD Load() - { - string reg = null; - - switch (Region()) - { - case 0: - reg = " (USA)"; - break; - - case 1: - case 2: - reg = " (Europe)"; - break; - - case 3: - reg = " (Japan)"; - break; - - case 4: - reg = " (Korea) (Ja,Ko)"; - break; - - case 5: - reg = " (Korea) (En,Ko)"; - break; - } - - Console c = DatabaseHelper.Console(TitleID); - string ConsoleType = c == Console.NES ? " (NES)" - : c == Console.SNES ? " (SNES)" - : c == Console.N64 ? " (N64)" - : c == Console.SMS ? " (SMS)" - : c == Console.SMD ? " (SMD)" - : c == Console.PCE ? " (TGX)" - : c == Console.NEO ? " (NG)" - : c == Console.C64 ? " (C64)" - : c == Console.MSX ? " (MSX)" - : null; - - if (reg == null) throw new ArgumentException(); - - // Load WAD from MarioCube. - // ------------------------------------------------ - // Sadly, as the NUS downloader cannot decrypt VC/Wii Shop titles on its own without needing the ticket file, I have done a less copyright-friendly workaround solution for now - // Direct link is not included, for obvious reasons! - // **************** - string name = Name + reg + ConsoleType; - string URL = "https://repo.mariocube.com/WADs/_WiiWare,%20VC,%20DLC,%20Channels%20&%20IOS/" + name[0].ToString().ToUpper() + "/" + Uri.EscapeDataString(name + " (Virtual Console)") + ".wad"; - if (c == Console.Flash) URL = "https://repo.mariocube.com/WADs/Flash%20Injects/Base/" + Uri.EscapeDataString(name) + ".wad"; - - Web.InternetTest(); - - WAD w = WAD.Load(Web.Get(URL)); - - // Title ID check - // **************** - if ((w.UpperTitleID.ToUpper() != TitleID.ToUpper() && c != Console.Flash) || !w.HasBanner) throw new ArgumentException(); - return w; - } - - public enum Regions - { - All, - USA, - USA_JP, - Europe, - Europe_JP, - Europe_US, - Japan, - Korea_JA, - Korea_EN, - } - - public int Region() - { - char RegionCode = TitleID.ToUpper()[3]; - - switch (RegionCode) - { - default: - case 'E': // USA - case 'N': - return 0; - - case 'P': - return 1; - - case 'L': // Japanese import - case 'M': // American import - return 2; - - case 'J': // Japan - return 3; - - case 'Q': // Korea with Japanese language - return 4; - - case 'T': // Korea with English language - return 5; - } - } - - public DatabaseEntry() { } - } - - - public static class DatabaseHelper - { - public static DatabaseEntry[] Get(Console c) - { - foreach (Database item in XmlHelper.FromXml(Properties.Resources.Database)) - if (item.Type == c) return item.Entries; - - return null; - } - - public static Console Console(string tID) - { - var items = XmlHelper.FromXml(Properties.Resources.Database); - - foreach (Database item in items) - { - for (int i = 0; i < item.Entries.Length; i++) - { - if (item.Entries[i].TitleID.ToUpper() == tID.ToUpper()) - { - return item.Type; - } - } - } - - return 0; - } - - public static DatabaseEntry Get(string tID) - { - var items = XmlHelper.FromXml(Properties.Resources.Database); - - foreach (Database item in items) - { - for (int i = 0; i < item.Entries.Length; i++) - { - if (item.Entries[i].TitleID.ToUpper() == tID.ToUpper()) - { - return item.Entries[i]; - } - } - } - - return null; - } - - public static DatabaseEntry Get(string tID, Console c) - { - var List = Get(c); - - for (int i = 0; i < List.Length; i++) - { - if (List[i].TitleID.ToUpper() == tID.ToUpper()) - { - return List[i]; - } - } - - return null; - } - } -} diff --git a/FriishProduce/_classes/Modifiers/WiiVC.cs b/FriishProduce/_classes/Modifiers/WiiVC.cs index 4e926f1e..37cc264c 100644 --- a/FriishProduce/_classes/Modifiers/WiiVC.cs +++ b/FriishProduce/_classes/Modifiers/WiiVC.cs @@ -133,6 +133,32 @@ protected U8 ReplaceManual() return ManualArc; } + protected CCF ReplaceManual(CCF target) + { + // Get and read emanual + // **************** + try + { + if (ManualPath != null) + { + foreach (var item in target.Nodes) + if (item.Name.ToLower().Contains("man.arc")) + { + OrigManual = item.Name; + Manual = target.Data[target.GetNodeIndex(OrigManual)]; + + target.ReplaceFile(target.GetNodeIndex(OrigManual), ReplaceManual().ToByteArray()); + } + } + } + + catch + { + } + + return target; + } + protected void ReplaceManual(U8 target) { if (ManualPath == null) @@ -144,29 +170,17 @@ protected void ReplaceManual(U8 target) { /* For reference: copied from "vcromclaim": https://github.com/JanErikGunnar/vcromclaim/blob/master/wiimetadata.py - if u8arc.findfile('emanual.arc'): - man = U8Archive(u8arc.getfile(u8arc.findfile('emanual.arc'))) - - elif u8arc.findfile('html.arc'): - man = U8Archive(u8arc.getfile(u8arc.findfile('html.arc'))) - - elif u8arc.findfile('man.arc'): - man = U8Archive(u8arc.getfile(u8arc.findfile('man.arc'))) + NOT COMPRESSED: - elif u8arc.findfile('data.ccf'): - ccf = CCFArchive(u8arc.getfile(u8arc.findfile('data.ccf'))) - man = U8Archive(ccf.getfile('man.arc')) + emanual.arc + html.arc + man.arc + data.ccf > man.arc - elif u8arc.findfile('htmlc.arc'): - manc = u8arc.getfile(u8arc.findfile('htmlc.arc')) - print('Decompressing manual: htmlc.arc') - man = U8Archive(BytesIO(lz77.decompress_n64(manc))) + COMPRESSED: - elif u8arc.findfilebyregex('.+_manual_.+\\.arc\\.lz77$'): - # E.g. makaimura_manual_usa.arc.lz77 (Arcade Ghosts n Goblins) - manc = u8arc.getfile(u8arc.findfilebyregex('.+_manual_.+\\.arc\\.lz77$')) - man = U8Archive(BytesIO(lz77.decompress_nonN64(manc))) - manc.close() */ + htmlc.arc (N64 LZ77) + Regex('.+_manual_.+\\.arc\\.lz77$') e.g. makaimura_manual_usa.arc.lz77 (Arcade Ghosts n Goblins) */ // Get and read emanual // **************** diff --git a/FriishProduce/_classes/Program/Database.cs b/FriishProduce/_classes/Program/Database.cs new file mode 100644 index 00000000..5478076f --- /dev/null +++ b/FriishProduce/_classes/Program/Database.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization.Metadata; +using libWiiSharp; + +namespace FriishProduce +{ + public class Database + { + + public class DatabaseEntry + { + public string ID { get; set; } + public List Regions = new List(); + public List Titles = new List(); + public List EmuRevs = new List(); + + public string GetID(int index) + { + string r = "41"; + + switch (Regions[index]) + { + default: + case 0: + r = "4a"; + break; + + case 1: + r = "45"; + break; + + case 2: + r = "4e"; + break; + + case 3: + r = "50"; + break; + + case 4: + r = "4c"; + break; + + case 5: + r = "4d"; + break; + + case 6: + r = "51"; + break; + + case 7: + r = "54"; + break; + } + + return ID.Replace("__", r).ToLower(); + } + + public string GetUpperID(int index) + { + var hex = GetID(index).Substring(ID.Length - 8); + var ascii = string.Empty; + + + for (int i = 0; i < hex.Length; i += 2) + { + var hs = hex.Substring(i, 2); + char character = Convert.ToChar(Convert.ToInt64(hs, 16)); + ascii += character; + } + + return ascii; + } + + /// + /// Gets a WAD file from the entry corresponding to the index entered and loads it to memory. + /// + public WAD GetWAD(int index) + { + throw new NotImplementedException(); + return new WAD(); + } + } + + public List Entries { get; private set; } + + /// + /// Loads a database of WADs for a selected console/platform. + /// + public Database(Console c) + { + try + { + using (MemoryStream ms = new MemoryStream(Properties.Resources.Database)) + using (StreamReader sr = new StreamReader(ms, Encoding.Unicode)) + using (var doc = JsonDocument.Parse(sr.ReadToEnd(), new JsonDocumentOptions() { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip })) + { + var x = doc.Deserialize(new JsonSerializerOptions() { AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip }).GetProperty(c.ToString().ToLower()); + if (x.ValueKind != JsonValueKind.Array) throw new Exception("The database format or styling is not valid."); + + sr.Dispose(); + ms.Dispose(); + + Entries = new List(); + foreach (var item in x.EnumerateArray()) + { + var y = new DatabaseEntry() { ID = item.GetProperty("id").GetString() }; + var reg = item.GetProperty("region"); + + for (int i = 0; i < reg.GetArrayLength(); i++) + { + y.Regions.Add(reg[i].GetInt32()); + try { y.Titles.Add(item.GetProperty("titles")[i].GetString()); } catch { y.Titles.Add(item.GetProperty("titles")[Math.Max(0, item.GetProperty("titles").GetArrayLength() - 1)].GetString()); } + try { y.EmuRevs.Add(item.GetProperty("emu_ver")[i].GetInt32()); } catch { y.EmuRevs.Add(0); } + } + + Entries.Add(y); + } + } + } + + catch (Exception ex) + { + System.Windows.Forms.MessageBox.Show($"A fatal error occurred retrieving the {c} WADs database.\n\nException: {ex.GetType().FullName}\nMessage: {ex.Message}\n\nThe application will now shut down.", "Halt", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); + Environment.FailFast("Database initialization failed."); + } + } + } +} diff --git a/FriishProduce/_classes/Program/Language.cs b/FriishProduce/_classes/Program/Language.cs index dd7ffd97..12e619ba 100644 --- a/FriishProduce/_classes/Program/Language.cs +++ b/FriishProduce/_classes/Program/Language.cs @@ -97,7 +97,7 @@ public Language(string code = null) catch (Exception ex) { - System.Windows.Forms.MessageBox.Show($"A fatal error occurred initializing the program, as the English string resource file was not found or is invalid.\n\nException: {ex.GetType().FullName}\nMessage: {ex.Message}\n\nThe application will now shut down.", "Halt", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); + System.Windows.Forms.MessageBox.Show($"A fatal error occurred initializing the program, as the English string resource file was not found or is invalid.\n\nException: {ex.GetType().FullName}\nMessage: {ex.Message}\n\nThe application will now shut down.", "Halt", MessageBoxButtons.OK, MessageBoxIcon.Hand); Environment.FailFast("Language initialization failed."); } } @@ -129,7 +129,7 @@ public Language(string code = null) else _current = parseFile(GetSystemLanguage()); if (string.IsNullOrEmpty(_current.language)) _current = _english; - else if (_current.language != code) code = _current.language; + else if (_current.language != code) _current.language = code; if (_current == null) { diff --git a/FriishProduce/database.json b/FriishProduce/database.json index 5f68ba09..8acc8efc 100644 --- a/FriishProduce/database.json +++ b/FriishProduce/database.json @@ -1,93 +1,287 @@ { - "HOW TO ADD BASES": - { - "// id": "The full ID of the channel in hex, except the last two characters (replace with '__' two underscores). This is the region component for the title ID and will be determined automatically by the app.", - "Example": "00010001-464357__ (FCW_)", - - "// region": "The regions for which the channel is available, in an array, listed by number.", - [ - "0": "Japan", - "1": "USA", - "2": "USA (Japanese import)", - "3": "Europe", - "4": "Europe (Japanese import/PAL60)", - "5": "Europe (American import/PAL60)", - "6": "Korea (Japanese language)", - "7": "Korea (English language)" - ], - - "// emu_ver": "The emulator version(s) corresponding to the WAD for each region, in an array. MUST be an integer!", - [ - "NES": [ - "Normal": 0, - "LZ77": 1, - "LZH8": 2 - ], - - "SNES": [ - "Normal": 0, - "LZ77": 1, - "LZH8": 2 - ], - - "N64": [ - "Rev 1": 0, - "Rev 1 (alternative savedata format)": 1, - "Rev 2 (legacy configuration removed)": 2, - "Rev 3 (ROMC)": 3 - ], - - "SMS": "Same as SMD, see below", - - "SMD": [ - "Rev 1 (has regional banner_XX.wte files for savedata)": 1, - "Rev 2 (may use 'patch' file, more settings)": 2, - "Rev 3 (includes modules and controller config)": 3 - ] - ], - - "// titles": "The regional software titles for the channel, by order of regions listed.", - [ - "Example 1": ["ゼルダの伝説", "The Legend of Zelda", "The Legend of Zelda"], - "Example 2": ["スターフォックス64", "Star Fox 64", "Lylat Wars"], - ] - }, - - - - "NES": [ - { - "id": "00010001-464357__", - "region": [0, 1, 3, 6], - "emu_ver": [0, 0, 0, 0], - "titles": ["スーパーマリオブラザーズ3", "Super Mario Bros. 3", "Super Mario Bros. 3", "슈퍼 마리오브라더스 3"] - }, - { - "id": "00010001-464138__", - "region": [0, 1, 3, 7], - "emu_ver": [0, 0, 0, 0], - "titles": ["星のカービィ 夢の泉の物語", "Kirby's Adventure", "Kirby's Adventure", "별의 커비 꿈의 샘 이야기"] - }, - { - "id": "00010001-46424e__", - "region": [5], - "emu_ver": [0], - "titles": ["Ninja Gaiden"] - } - ], - - "SNES": [ - { - "id": "00010001-4a4244__", - "region": [0, 1, 3, 7], - "emu_ver": [0, 0, 0, 0], - "titles": ["スーパードンキーコング2", "Donkey Kong Country 2", "Donkey Kong Country 2", "동키콩 컨트리 2"] - }, - { - "id": "00010001-4a4142__", - "region": [4], - "emu_ver": [0], - "titles": ["Mario's Super Picross"] - } - ] + // HOW TO ADD BASES + // "id" + // The full ID of the channel in hex, except the last two characters (replace with '__' two underscores). This is the region component for the title ID and will be determined automatically by the app. + + // Example: "00010001-464357__" (FCW_) + // _____________________________________________ + + // "region" + // The regions for which the channel is available, in an array, listed by number. + + // Available regions: + // "0": Japan + // "1": USA + // "2": USA (Japanese import) + // "3": Europe + // "4": Europe (Japanese import/PAL60) + // "5": Europe (American import/PAL60) + // "6": Korea (Japanese language) + // "7": Korea (English language) + // _____________________________________________ + + // "emu_ver" + // The emulator version(s) corresponding to the WAD for each region, in an array. MUST be an integer! + + // Emulator version entries: + // NES & SNES: + // "0": Original + // "1": LZ77 ROM + // "2": LZH8 ROM + // N64: + // "0": Rev 1 + // "1": Rev 1 (alternative savedata format) + // "2": Rev 2 (legacy configuration removed) + // "3": Rev 3 (ROMC) + // SMS & SMD: + // "1": Rev 1 (has regional banner_XX.wte files for savedata) + // "2": Rev 2 (may use 'patch' file, more settings) + // "3": Rev 3 (includes modules and controller config) + // _____________________________________________ + + // "titles" + // The regional software titles for the channel, by order of regions listed. + // The European title, if included, can be a duplicate English entry or the regionalised version of the game's title. + // If the game has a Korean VC WAD released, the European title MUST be included so that the database can handle the array correctly. + // Otherwise, if the game uses only a Japanese and universal English title pair or just the English one, there is no need for an additional European title entry. + + // Examples: + // ["ゼルダの伝説", "The Legend of Zelda"] (universal English title) + // ["スターフォックス64", "Star Fox 64", "Lylat Wars"] (additional European title) + // ["スーパードンキーコング2", "Donkey Kong Country 2", "Donkey Kong Country 2", "동키콩 컨트리 2"] (has Korean) + // _____________________________________________ + + "nes": [ + { + "id": "00010001-464357__", + "region": [0, 1, 3, 6], + "emu_ver": [0, 0, 0, 0], + "titles": ["スーパーマリオブラザーズ3", "Super Mario Bros. 3", "Super Mario Bros. 3", "슈퍼 마리오브라더스 3"] + }, + { + "id": "00010001-464138__", + "region": [0, 1, 3, 7], + "emu_ver": [0, 0, 0, 0], + "titles": ["星のカービィ 夢の泉の物語", "Kirby's Adventure", "Kirby's Adventure", "별의 커비 꿈의 샘 이야기"] + }, + { + "id": "00010001-46424e__", + "region": [5], + "emu_ver": [0], + "titles": ["Ninja Gaiden"] + } + ], + + "snes": [ + { + "id": "00010001-4a4244__", + "region": [0, 1, 3, 7], + "emu_ver": [0, 0, 0, 0], + "titles": ["スーパードンキーコング2", "Donkey Kong Country 2", "Donkey Kong Country 2", "동키콩 컨트리 2"] + }, + { + "id": "00010001-4a4142__", + "region": [4], + "emu_ver": [0], + "titles": ["Mario's Super Picross"] + } + ], + + "n64": [ + { + "id": "00010001-4e4141__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["スーパーマリオ64", "Super Mario 64"] + }, + + { + "id": "00010001-4e4146__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["F-ZERO X", "F-Zero X"] + }, + + { + "id": "00010001-4e4144__", + "region": [0, 1, 3, 7], + "emu_ver": [1, 1, 1, 3], + "titles": ["スターフォックス64", "Star Fox 64", "Lylat Wars", "스타폭스 64"] + }, + + { + "id": "00010001-4e4142__", + "region": [0, 1, 3, 7], + "emu_ver": [1, 1, 1, 3], + "titles": ["マリオカート64", "Mario Kart 64", "Mario Kart 64", "마리오 카트 64"] + }, + + { + "id": "00010001-4e4143__", + "region": [0, 1, 3], + "emu_ver": [1, 1, 1], + "titles": ["ゼルダの伝説 時のオカリナ", "The Legend of Zelda: Ocarina of Time"] + }, + + { + "id": "00010001-4e414a__", + "region": [0, 2, 4], + "emu_ver": [2, 2, 2], + "titles": ["罪と罰 〜地球の継承者〜", "Sin and Punishment"] + }, + + { + "id": "00010001-4e414b__", + "region": [0, 2, 4], + "emu_ver": [2, 2, 2], + "titles": ["ポケモンスナップ", "Pokémon Snap"] + }, + + { + "id": "00010001-4e4150__", + "region": [0], + "emu_ver": [3], + "titles": ["カスタムロボV2(Custom Robo V2)"] + }, + + { + "id": "00010001-4e4133__", + "region": [0, 1, 3], + "emu_ver": [3, 3, 3], + "titles": ["ボンバーマンヒーロー ミリアン王女を救え!", "Bomberman Hero"] + }, + + { + "id": "00010001-4e4155__", + "region": [0, 1, 3], + "emu_ver": [3, 3, 3], + "titles": ["マリオゴルフ64", "Mario Golf"] + }, + + { + "id": "00010001-4e4159__", + "region": [0, 1, 5], + "emu_ver": [3, 3, 3], + "titles": ["オウガバトル64", "Ogre Battle 64: Person of Lordly Caliber"] + }, + ], + + "sms": [ + { + "id": "00010001-4c4147__", + "region": [0, 1, 3], + "emu_ver": [2, 2, 2], + "titles": ["ソニック・ザ・ヘッジホッグ", "Sonic the Hedgehog"] + }, + + { + "id": "00010001-4c4144__", + "region": [0, 1, 3], + "emu_ver": [3, 3, 2], + "titles": ["ファンタシースター", "Phantasy Star"] + } + ], + + "smd": [ + { + "id": "00010001-4d4136__", + "region": [0, 1, 3], + "emu_ver": [2, 2, 2], + "titles": ["ベア・ナックルII 死闘への鎮魂歌", "Streets of Rage 2"] + }, + + { + "id": "00010001-4d4241__", + "region": [0, 2, 4], + "emu_ver": [3, 3, 2], + "titles": ["ファンタシースター", "Pulseman"] + } + ], + + "pce": [ + { + "id": "00010001-504147__", + "region": [0, 2, 4], + "emu_ver": [0, 0, 0], + "titles": ["ボンバーマン’94", "Bomberman '94"] + }, + + { + "id": "00010001-504141__", + "region": [1, 3], + "emu_ver": [0, 0, 0], + "titles": ["Bomberman '93"] + }, + + { + "id": "00010001-504143__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["ダンジョン エクスプローラー", "Dungeon Explorer"] + }, + + { + "id": "00010001-504145__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["スーパースターソルジャー", "Super Star Soldier"] + }, + ], + + "neo": [ + { + "id": "00010001-454147__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["ザ・キングオブファイターズ94", "The King of Fighters '94"] + }, + + { + "id": "00010001-45414a__", + "region": [0, 1, 3], + "emu_ver": [0, 0, 0], + "titles": ["メタルスラッグ", "Metal Slug"] + }, + + { + "id": "00010001-454156__", + "region": [0, 1, 3], + "emu_ver": [1, 1, 1], + "titles": ["ザ・キングオブファイターズ95", "The King of Fighters '95"] + }, + ], + + "c64": [ + { + "id": "00010001-433959__", + "region": [1, 3], + "emu_ver": [0, 0], + "titles": ["International Karate"] + }, + ], + + "msx": [ + { + "id": "00010001-584147__", + "region": [0], + "emu_ver": [0], + "titles": ["ロードファイター Road Fighter"] + }, + + { + "id": "00010001-584150__", + "region": [0], + "emu_ver": [0], + "titles": ["メタルギア2 ソリッドスネーク"] + }, + ], + + "flash": [ + { + "id": "00010001-574e41__", + "region": [1, 3], + "emu_ver": [0, 0], + "titles": ["Flash Placeholder"] + } + ] } \ No newline at end of file