diff --git a/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj b/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj new file mode 100644 index 0000000000..289df0dfe3 --- /dev/null +++ b/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj @@ -0,0 +1,107 @@ + + + + + Debug + AnyCPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} + WinExe + Properties + BizHawk.Client.DBMan + BizHawk.Client.DBMan + v4.0 + 512 + + + + x86 + true + full + false + ..\output\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\output\ + TRACE + prompt + 4 + + + + .\CSharp-SQLite.dll + + + + + + + + + + + Form + + + DBMan_MainForm.cs + + + + + + + DBMan_MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {24a0aa3c-b25f-4197-b23d-476d6462dba0} + BizHawk.Client.Common + + + {866f8d13-0678-4ff9-80a4-a3993fd4d8a3} + BizHawk.Common + + + {e1a23168-b571-411c-b360-2229e7225e0e} + BizHawk.Emulation.Common + + + {f51946ea-827f-4d82-b841-1f2f6d060312} + BizHawk.Emulation.DiscSystem + + + + + \ No newline at end of file diff --git a/BizHawk.Client.DBMan/CSharp-SQLite.dll b/BizHawk.Client.DBMan/CSharp-SQLite.dll new file mode 100644 index 0000000000..e0f7f7bcb6 Binary files /dev/null and b/BizHawk.Client.DBMan/CSharp-SQLite.dll differ diff --git a/BizHawk.Client.DBMan/DB.cs b/BizHawk.Client.DBMan/DB.cs new file mode 100644 index 0000000000..6f1f2ccbb5 --- /dev/null +++ b/BizHawk.Client.DBMan/DB.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Community.CsharpSqlite.SQLiteClient; + +namespace BizHawk.Client.DBMan +{ + public class Rom + { + public long RomId; + public string CRC32; + public string MD5; + public string SHA1; + public string System; + public string Name; + public string Region; + public string VersionTags; + public string RomMetadata; + public string RomStatus; + public string Catalog; + + public override string ToString() { return Name + " " + VersionTags; } + public Game Game; + public string CombinedMetaData + { + get + { + if (Game == null) return RomMetadata; + if (Game.GameMetadata == null) return RomMetadata; + if (RomMetadata == null) return Game.GameMetadata; + return Game.GameMetadata + ";" + RomMetadata; + } + } + } + + public class Game + { + public long GameId; + public string System; + public string Name; + public string Developer; + public string Publisher; + public string Classification; + public string ReleaseDate; + public string Players; + public string GameMetadata; + public string Tags; + public string AltNames; + public string Notes; + + public override string ToString() { return Name; } + } + + public static class DB + { + public static List Roms = new List(); + public static List Games = new List(); + public static Dictionary GameMap = new Dictionary(); + + public static SqliteConnection Con; + + public static void LoadDbForSystem(string system) + { + Games.Clear(); + Roms.Clear(); + + LoadGames(system); + LoadRoms(system); + } + + static void LoadGames(string system) + { + var cmd = Con.CreateCommand(); + cmd.CommandText = "SELECT game_id, system, name, developer, publisher, classification, release_date, players, game_metadata, tags, alternate_names, notes FROM game WHERE system = @System"; + cmd.Parameters.Add(new SqliteParameter("@System", system)); + var reader = cmd.ExecuteReader(); + while (reader.NextResult()) + { + var game = new Game(); + game.GameId = reader.GetInt64(0); + game.System = reader.GetString(1); + game.Name = reader.GetString(2); + game.Developer = reader.GetString(3); + game.Publisher = reader.GetString(4); + game.Classification = reader.GetString(5); + game.ReleaseDate = reader.GetString(6); + game.Players = reader.GetString(7); + game.GameMetadata = reader.GetString(8); + game.Tags = reader.GetString(9); + game.AltNames = reader.GetString(10); + game.Notes = reader.GetString(11); + Games.Add(game); + GameMap[game.Name] = game; + } + reader.Dispose(); + cmd.Dispose(); + } + + static void LoadRoms(string system) + { + var cmd = Con.CreateCommand(); + cmd.CommandText = "SELECT rom_id, crc32, md5, sha1, system, name, region, version_tags, rom_metadata, rom_status, catalog FROM rom WHERE system = @System"; + cmd.Parameters.Add(new SqliteParameter("@System", system)); + var reader = cmd.ExecuteReader(); + while (reader.NextResult()) + { + var rom = new Rom(); + rom.RomId = reader.GetInt64(0); + rom.CRC32 = reader.GetString(1); + rom.MD5 = reader.GetString(2); + rom.SHA1 = reader.GetString(3); + rom.System = reader.GetString(4); + rom.Name = reader.GetString(5); + rom.Region = reader.GetString(6); + rom.VersionTags = reader.GetString(7); + rom.RomMetadata = reader.GetString(8); + rom.RomStatus = reader.GetString(9); + rom.Catalog = reader.GetString(10); + rom.Game = GameMap[rom.Name]; + Roms.Add(rom); + } + reader.Dispose(); + cmd.Dispose(); + } + + public static void SaveRom(Rom rom) + { + var cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE rom SET "+ + "region=@Region, "+ + "version_tags=@VersionTags, "+ + "rom_metadata=@RomMetadata, "+ + "rom_status=@RomStatus, "+ + "catalog=@Catalog " + + "WHERE rom_id=@RomId"; + cmd.Parameters.Add(new SqliteParameter("@Region", rom.Region)); + cmd.Parameters.Add(new SqliteParameter("@VersionTags", rom.VersionTags)); + cmd.Parameters.Add(new SqliteParameter("@RomMetadata", rom.RomMetadata)); + cmd.Parameters.Add(new SqliteParameter("@RomStatus", rom.RomStatus)); + cmd.Parameters.Add(new SqliteParameter("@Catalog", rom.Catalog)); + cmd.Parameters.Add(new SqliteParameter("@RomId", rom.RomId)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + + cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE game SET "+ + "developer=@Developer, "+ + "publisher=@Publisher, "+ + "classification=@Classification, "+ + "release_date=@ReleaseDate, "+ + "players=@Players, "+ + "game_metadata=@GameMetadata, "+ + "tags=@Tags, "+ + "alternate_names=@AltNames, "+ + "notes=@Notes "+ + "WHERE game_id=@GameId"; + cmd.Parameters.Add(new SqliteParameter("@Developer", rom.Game.Developer)); + cmd.Parameters.Add(new SqliteParameter("@Publisher", rom.Game.Publisher)); + cmd.Parameters.Add(new SqliteParameter("@Classification", rom.Game.Classification)); + cmd.Parameters.Add(new SqliteParameter("@ReleaseDate", rom.Game.ReleaseDate)); + cmd.Parameters.Add(new SqliteParameter("@Players", rom.Game.Players)); + cmd.Parameters.Add(new SqliteParameter("@GameMetadata", rom.Game.GameMetadata)); + cmd.Parameters.Add(new SqliteParameter("@Tags", rom.Game.Tags)); + cmd.Parameters.Add(new SqliteParameter("@AltNames", rom.Game.AltNames)); + cmd.Parameters.Add(new SqliteParameter("@Notes", rom.Game.Notes)); + cmd.Parameters.Add(new SqliteParameter("@GameId", rom.Game.GameId)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + + public static void SaveRom1(Rom rom, string origSystem, string origName) + { + var cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE rom SET " + + "system=@System, " + + "name=@Name " + + "WHERE system=@OrigSystem and name=@OrigName"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.Parameters.Add(new SqliteParameter("@OrigSystem", origSystem)); + cmd.Parameters.Add(new SqliteParameter("@OrigName", origName)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + + cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE game SET " + + "system=@System, " + + "name=@Name " + + "WHERE system=@OrigSystem and name=@OrigName"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.Parameters.Add(new SqliteParameter("@OrigSystem", origSystem)); + cmd.Parameters.Add(new SqliteParameter("@OrigName", origName)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + + SaveRom(rom); + } + + public static void SaveRom2(Rom rom) + { + var cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE rom SET " + + "system=@System, "+ + "name=@Name, "+ + "region=@Region, " + + "version_tags=@VersionTags, " + + "rom_metadata=@RomMetadata, " + + "rom_status=@RomStatus, " + + "catalog=@Catalog " + + "WHERE rom_id=@RomId"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.Parameters.Add(new SqliteParameter("@Region", rom.Region)); + cmd.Parameters.Add(new SqliteParameter("@VersionTags", rom.VersionTags)); + cmd.Parameters.Add(new SqliteParameter("@RomMetadata", rom.RomMetadata)); + cmd.Parameters.Add(new SqliteParameter("@RomStatus", rom.RomStatus)); + cmd.Parameters.Add(new SqliteParameter("@Catalog", rom.Catalog)); + cmd.Parameters.Add(new SqliteParameter("@RomId", rom.RomId)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + + bool gameAlreadyExists = false; + cmd = Con.CreateCommand(); + cmd.CommandText = "SELECT game_id FROM game WHERE system=@System and name=@Name"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + gameAlreadyExists = cmd.ExecuteScalar() != null; + cmd.Dispose(); + + if (!gameAlreadyExists) + { + cmd = Con.CreateCommand(); + cmd.CommandText = "INSERT INTO game (system, name) values (@System, @Name)"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + + cmd = Con.CreateCommand(); + cmd.CommandText = + "UPDATE game SET " + + "developer=@Developer, " + + "publisher=@Publisher, " + + "classification=@Classification, " + + "release_date=@ReleaseDate, " + + "players=@Players, " + + "game_metadata=@GameMetadata, " + + "tags=@Tags, " + + "alternate_names=@AltNames, " + + "notes=@Notes " + + "WHERE system=@System and name=@Name"; + cmd.Parameters.Add(new SqliteParameter("@Developer", rom.Game.Developer)); + cmd.Parameters.Add(new SqliteParameter("@Publisher", rom.Game.Publisher)); + cmd.Parameters.Add(new SqliteParameter("@Classification", rom.Game.Classification)); + cmd.Parameters.Add(new SqliteParameter("@ReleaseDate", rom.Game.ReleaseDate)); + cmd.Parameters.Add(new SqliteParameter("@Players", rom.Game.Players)); + cmd.Parameters.Add(new SqliteParameter("@GameMetadata", rom.Game.GameMetadata)); + cmd.Parameters.Add(new SqliteParameter("@Tags", rom.Game.Tags)); + cmd.Parameters.Add(new SqliteParameter("@System", rom.System)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.Parameters.Add(new SqliteParameter("@AltNames", rom.Game.AltNames)); + cmd.Parameters.Add(new SqliteParameter("@Notes", rom.Game.Notes)); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + + public static void Cleanup() + { + var orphanedGameList = new List>(); + + var cmd = Con.CreateCommand(); + cmd.CommandText = + "SELECT system, name FROM game "+ + "EXCEPT "+ + "SELECT system, name FROM rom"; + var reader = cmd.ExecuteReader(); + while (reader.NextResult()) + { + string system = reader.GetString(0); + string name = reader.GetString(1); + orphanedGameList.Add(new Tuple(system, name)); + } + reader.Dispose(); + cmd.Dispose(); + + cmd = Con.CreateCommand(); + cmd.CommandText = "DELETE FROM game WHERE system=@System and name=@Name"; + foreach (var orphanedGame in orphanedGameList) + { + cmd.Parameters.Clear(); + cmd.Parameters.Add(new SqliteParameter("@System", orphanedGame.Item1)); + cmd.Parameters.Add(new SqliteParameter("@Name", orphanedGame.Item2)); + cmd.ExecuteNonQuery(); + } + cmd.Dispose(); + + cmd = Con.CreateCommand(); + cmd.CommandText = "VACUUM"; + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + + public static List GetDeveloperPublisherNames() + { + var names = new List(); + + var cmd = Con.CreateCommand(); + cmd.CommandText = + "SELECT DISTINCT developer FROM game WHERE developer is not null " + + "UNION " + + "SELECT DISTINCT publisher FROM game WHERE publisher is not null"; + var reader = cmd.ExecuteReader(); + while (reader.NextResult()) + { + names.Add(reader.GetString(0)); + } + reader.Dispose(); + cmd.Dispose(); + + return names; + } + } +} diff --git a/BizHawk.Client.DBMan/DBMan_MainForm.Designer.cs b/BizHawk.Client.DBMan/DBMan_MainForm.Designer.cs new file mode 100644 index 0000000000..06a6c989dc --- /dev/null +++ b/BizHawk.Client.DBMan/DBMan_MainForm.Designer.cs @@ -0,0 +1,746 @@ +namespace BizHawk.Client.DBMan +{ + partial class DBMan_MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.filterPanel = new System.Windows.Forms.Panel(); + this.whereLabel = new System.Windows.Forms.Label(); + this.systemBox = new System.Windows.Forms.ComboBox(); + this.whereBox = new System.Windows.Forms.TextBox(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.romListView = new System.Windows.Forms.ListView(); + this.romListColumnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.romListColumnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.romListColumnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.romListColumnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.romListColumnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.detailPanel = new System.Windows.Forms.Panel(); + this.developerLabel = new System.Windows.Forms.Label(); + this.developerBox = new System.Windows.Forms.TextBox(); + this.romStatusLabel = new System.Windows.Forms.Label(); + this.romStatusBox = new System.Windows.Forms.ComboBox(); + this.tagsLabel = new System.Windows.Forms.Label(); + this.tagsBox = new System.Windows.Forms.TextBox(); + this.romMetaLabel = new System.Windows.Forms.Label(); + this.romMetaBox = new System.Windows.Forms.TextBox(); + this.gameMetaLabel = new System.Windows.Forms.Label(); + this.gameMetaBox = new System.Windows.Forms.TextBox(); + this.versionLabel = new System.Windows.Forms.Label(); + this.versionBox = new System.Windows.Forms.TextBox(); + this.regionLabel = new System.Windows.Forms.Label(); + this.regionBox = new System.Windows.Forms.TextBox(); + this.sha1Box = new System.Windows.Forms.TextBox(); + this.md5Box = new System.Windows.Forms.TextBox(); + this.crcBox = new System.Windows.Forms.TextBox(); + this.sha1Label = new System.Windows.Forms.Label(); + this.md5Label = new System.Windows.Forms.Label(); + this.crcLabel = new System.Windows.Forms.Label(); + this.gameSystemBox = new System.Windows.Forms.ComboBox(); + this.systemLabel = new System.Windows.Forms.Label(); + this.nameBox = new System.Windows.Forms.TextBox(); + this.nameLabel = new System.Windows.Forms.Label(); + this.mainMenuStrip = new System.Windows.Forms.MenuStrip(); + this.databaseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.directoryScanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.publisherBox = new System.Windows.Forms.TextBox(); + this.publisherLabel = new System.Windows.Forms.Label(); + this.classificationBox = new System.Windows.Forms.ComboBox(); + this.classificationLabel = new System.Windows.Forms.Label(); + this.releaseDateBox = new System.Windows.Forms.TextBox(); + this.releaseDateLabel = new System.Windows.Forms.Label(); + this.playersLabel = new System.Windows.Forms.Label(); + this.catalogBox = new System.Windows.Forms.TextBox(); + this.catalogLabel = new System.Windows.Forms.Label(); + this.playersBox = new System.Windows.Forms.TextBox(); + this.saveButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.cleanupDBToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.altNamesBox = new System.Windows.Forms.TextBox(); + this.altNamesLabel = new System.Windows.Forms.Label(); + this.notesBox = new System.Windows.Forms.TextBox(); + this.notesLabel = new System.Windows.Forms.Label(); + this.filterPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.detailPanel.SuspendLayout(); + this.mainMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // filterPanel + // + this.filterPanel.Controls.Add(this.whereLabel); + this.filterPanel.Controls.Add(this.systemBox); + this.filterPanel.Controls.Add(this.whereBox); + this.filterPanel.Controls.Add(this.menuStrip1); + this.filterPanel.Dock = System.Windows.Forms.DockStyle.Top; + this.filterPanel.Location = new System.Drawing.Point(0, 24); + this.filterPanel.Name = "filterPanel"; + this.filterPanel.Size = new System.Drawing.Size(963, 30); + this.filterPanel.TabIndex = 0; + // + // whereLabel + // + this.whereLabel.AutoSize = true; + this.whereLabel.Location = new System.Drawing.Point(131, 9); + this.whereLabel.Name = "whereLabel"; + this.whereLabel.Size = new System.Drawing.Size(42, 13); + this.whereLabel.TabIndex = 2; + this.whereLabel.Text = "Where:"; + // + // systemBox + // + this.systemBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.systemBox.FormattingEnabled = true; + this.systemBox.Location = new System.Drawing.Point(4, 3); + this.systemBox.Name = "systemBox"; + this.systemBox.Size = new System.Drawing.Size(121, 21); + this.systemBox.TabIndex = 1; + this.systemBox.SelectedIndexChanged += new System.EventHandler(this.systemBox_SelectedIndexChanged); + // + // whereBox + // + this.whereBox.Location = new System.Drawing.Point(179, 3); + this.whereBox.Name = "whereBox"; + this.whereBox.Size = new System.Drawing.Size(334, 20); + this.whereBox.TabIndex = 2; + // + // menuStrip1 + // + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(963, 24); + this.menuStrip1.TabIndex = 3; + this.menuStrip1.Text = "menuStrip1"; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 54); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.romListView); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.detailPanel); + this.splitContainer1.Size = new System.Drawing.Size(963, 588); + this.splitContainer1.SplitterDistance = 492; + this.splitContainer1.TabIndex = 0; + this.splitContainer1.TabStop = false; + // + // romListView + // + this.romListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.romListColumnHeader1, + this.romListColumnHeader2, + this.romListColumnHeader3, + this.romListColumnHeader4, + this.romListColumnHeader5}); + this.romListView.Dock = System.Windows.Forms.DockStyle.Fill; + this.romListView.FullRowSelect = true; + this.romListView.GridLines = true; + this.romListView.Location = new System.Drawing.Point(0, 0); + this.romListView.MultiSelect = false; + this.romListView.Name = "romListView"; + this.romListView.Size = new System.Drawing.Size(492, 588); + this.romListView.TabIndex = 0; + this.romListView.TabStop = false; + this.romListView.UseCompatibleStateImageBehavior = false; + this.romListView.View = System.Windows.Forms.View.Details; + this.romListView.SelectedIndexChanged += new System.EventHandler(this.selectedRomChanged); + this.romListView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.selectedRomMouseUp); + // + // romListColumnHeader1 + // + this.romListColumnHeader1.Text = "Game"; + this.romListColumnHeader1.Width = 86; + // + // romListColumnHeader2 + // + this.romListColumnHeader2.Text = "Region"; + this.romListColumnHeader2.Width = 80; + // + // romListColumnHeader3 + // + this.romListColumnHeader3.Text = "Version"; + this.romListColumnHeader3.Width = 80; + // + // romListColumnHeader4 + // + this.romListColumnHeader4.Text = "Meta"; + this.romListColumnHeader4.Width = 80; + // + // romListColumnHeader5 + // + this.romListColumnHeader5.Text = "Tags"; + // + // detailPanel + // + this.detailPanel.Controls.Add(this.notesLabel); + this.detailPanel.Controls.Add(this.notesBox); + this.detailPanel.Controls.Add(this.altNamesLabel); + this.detailPanel.Controls.Add(this.altNamesBox); + this.detailPanel.Controls.Add(this.cancelButton); + this.detailPanel.Controls.Add(this.saveButton); + this.detailPanel.Controls.Add(this.playersBox); + this.detailPanel.Controls.Add(this.catalogLabel); + this.detailPanel.Controls.Add(this.catalogBox); + this.detailPanel.Controls.Add(this.playersLabel); + this.detailPanel.Controls.Add(this.releaseDateLabel); + this.detailPanel.Controls.Add(this.releaseDateBox); + this.detailPanel.Controls.Add(this.classificationLabel); + this.detailPanel.Controls.Add(this.classificationBox); + this.detailPanel.Controls.Add(this.publisherLabel); + this.detailPanel.Controls.Add(this.publisherBox); + this.detailPanel.Controls.Add(this.developerLabel); + this.detailPanel.Controls.Add(this.developerBox); + this.detailPanel.Controls.Add(this.romStatusLabel); + this.detailPanel.Controls.Add(this.romStatusBox); + this.detailPanel.Controls.Add(this.tagsLabel); + this.detailPanel.Controls.Add(this.tagsBox); + this.detailPanel.Controls.Add(this.romMetaLabel); + this.detailPanel.Controls.Add(this.romMetaBox); + this.detailPanel.Controls.Add(this.gameMetaLabel); + this.detailPanel.Controls.Add(this.gameMetaBox); + this.detailPanel.Controls.Add(this.versionLabel); + this.detailPanel.Controls.Add(this.versionBox); + this.detailPanel.Controls.Add(this.regionLabel); + this.detailPanel.Controls.Add(this.regionBox); + this.detailPanel.Controls.Add(this.sha1Box); + this.detailPanel.Controls.Add(this.md5Box); + this.detailPanel.Controls.Add(this.crcBox); + this.detailPanel.Controls.Add(this.sha1Label); + this.detailPanel.Controls.Add(this.md5Label); + this.detailPanel.Controls.Add(this.crcLabel); + this.detailPanel.Controls.Add(this.gameSystemBox); + this.detailPanel.Controls.Add(this.systemLabel); + this.detailPanel.Controls.Add(this.nameBox); + this.detailPanel.Controls.Add(this.nameLabel); + this.detailPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.detailPanel.Location = new System.Drawing.Point(0, 0); + this.detailPanel.Name = "detailPanel"; + this.detailPanel.Size = new System.Drawing.Size(467, 588); + this.detailPanel.TabIndex = 0; + // + // developerLabel + // + this.developerLabel.AutoSize = true; + this.developerLabel.Location = new System.Drawing.Point(3, 217); + this.developerLabel.Name = "developerLabel"; + this.developerLabel.Size = new System.Drawing.Size(56, 13); + this.developerLabel.TabIndex = 31; + this.developerLabel.Text = "Developer"; + // + // developerBox + // + this.developerBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + this.developerBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + this.developerBox.Location = new System.Drawing.Point(80, 217); + this.developerBox.Name = "developerBox"; + this.developerBox.Size = new System.Drawing.Size(194, 20); + this.developerBox.TabIndex = 30; + // + // romStatusLabel + // + this.romStatusLabel.AutoSize = true; + this.romStatusLabel.Location = new System.Drawing.Point(3, 189); + this.romStatusLabel.Name = "romStatusLabel"; + this.romStatusLabel.Size = new System.Drawing.Size(62, 13); + this.romStatusLabel.TabIndex = 29; + this.romStatusLabel.Text = "Rom Status"; + // + // romStatusBox + // + this.romStatusBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.romStatusBox.FormattingEnabled = true; + this.romStatusBox.Items.AddRange(new object[] { + "Ok", + "Bad Dump", + "Hack", + "Translation", + "Overdump", + "Trained"}); + this.romStatusBox.Location = new System.Drawing.Point(80, 189); + this.romStatusBox.Name = "romStatusBox"; + this.romStatusBox.Size = new System.Drawing.Size(121, 21); + this.romStatusBox.TabIndex = 28; + // + // tagsLabel + // + this.tagsLabel.AutoSize = true; + this.tagsLabel.Location = new System.Drawing.Point(3, 162); + this.tagsLabel.Name = "tagsLabel"; + this.tagsLabel.Size = new System.Drawing.Size(31, 13); + this.tagsLabel.TabIndex = 27; + this.tagsLabel.Text = "Tags"; + // + // tagsBox + // + this.tagsBox.Location = new System.Drawing.Point(80, 162); + this.tagsBox.Name = "tagsBox"; + this.tagsBox.Size = new System.Drawing.Size(296, 20); + this.tagsBox.TabIndex = 26; + // + // romMetaLabel + // + this.romMetaLabel.AutoSize = true; + this.romMetaLabel.Location = new System.Drawing.Point(3, 135); + this.romMetaLabel.Name = "romMetaLabel"; + this.romMetaLabel.Size = new System.Drawing.Size(62, 13); + this.romMetaLabel.TabIndex = 25; + this.romMetaLabel.Text = "Meta (Rom)"; + // + // romMetaBox + // + this.romMetaBox.Location = new System.Drawing.Point(80, 135); + this.romMetaBox.Name = "romMetaBox"; + this.romMetaBox.Size = new System.Drawing.Size(296, 20); + this.romMetaBox.TabIndex = 24; + // + // gameMetaLabel + // + this.gameMetaLabel.AutoSize = true; + this.gameMetaLabel.Location = new System.Drawing.Point(3, 108); + this.gameMetaLabel.Name = "gameMetaLabel"; + this.gameMetaLabel.Size = new System.Drawing.Size(68, 13); + this.gameMetaLabel.TabIndex = 23; + this.gameMetaLabel.Text = "Meta (Game)"; + // + // gameMetaBox + // + this.gameMetaBox.Location = new System.Drawing.Point(80, 108); + this.gameMetaBox.Name = "gameMetaBox"; + this.gameMetaBox.Size = new System.Drawing.Size(296, 20); + this.gameMetaBox.TabIndex = 22; + // + // versionLabel + // + this.versionLabel.AutoSize = true; + this.versionLabel.Location = new System.Drawing.Point(3, 81); + this.versionLabel.Name = "versionLabel"; + this.versionLabel.Size = new System.Drawing.Size(42, 13); + this.versionLabel.TabIndex = 21; + this.versionLabel.Text = "Version"; + // + // versionBox + // + this.versionBox.Location = new System.Drawing.Point(80, 81); + this.versionBox.Name = "versionBox"; + this.versionBox.Size = new System.Drawing.Size(296, 20); + this.versionBox.TabIndex = 20; + // + // regionLabel + // + this.regionLabel.AutoSize = true; + this.regionLabel.Location = new System.Drawing.Point(3, 54); + this.regionLabel.Name = "regionLabel"; + this.regionLabel.Size = new System.Drawing.Size(41, 13); + this.regionLabel.TabIndex = 19; + this.regionLabel.Text = "Region"; + // + // regionBox + // + this.regionBox.AutoCompleteCustomSource.AddRange(new string[] { + "USA", + "Japan", + "Europe", + "Taiwan", + "Brazil", + "Korea"}); + this.regionBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + this.regionBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + this.regionBox.Location = new System.Drawing.Point(80, 54); + this.regionBox.Name = "regionBox"; + this.regionBox.Size = new System.Drawing.Size(194, 20); + this.regionBox.TabIndex = 18; + // + // sha1Box + // + this.sha1Box.Location = new System.Drawing.Point(80, 530); + this.sha1Box.Name = "sha1Box"; + this.sha1Box.ReadOnly = true; + this.sha1Box.Size = new System.Drawing.Size(296, 20); + this.sha1Box.TabIndex = 17; + this.sha1Box.TabStop = false; + // + // md5Box + // + this.md5Box.Location = new System.Drawing.Point(80, 503); + this.md5Box.Name = "md5Box"; + this.md5Box.ReadOnly = true; + this.md5Box.Size = new System.Drawing.Size(255, 20); + this.md5Box.TabIndex = 16; + this.md5Box.TabStop = false; + // + // crcBox + // + this.crcBox.Location = new System.Drawing.Point(80, 477); + this.crcBox.Name = "crcBox"; + this.crcBox.ReadOnly = true; + this.crcBox.Size = new System.Drawing.Size(100, 20); + this.crcBox.TabIndex = 15; + this.crcBox.TabStop = false; + // + // sha1Label + // + this.sha1Label.AutoSize = true; + this.sha1Label.Location = new System.Drawing.Point(3, 530); + this.sha1Label.Name = "sha1Label"; + this.sha1Label.Size = new System.Drawing.Size(35, 13); + this.sha1Label.TabIndex = 14; + this.sha1Label.Text = "SHA1"; + // + // md5Label + // + this.md5Label.AutoSize = true; + this.md5Label.Location = new System.Drawing.Point(3, 503); + this.md5Label.Name = "md5Label"; + this.md5Label.Size = new System.Drawing.Size(30, 13); + this.md5Label.TabIndex = 13; + this.md5Label.Text = "MD5"; + // + // crcLabel + // + this.crcLabel.AutoSize = true; + this.crcLabel.Location = new System.Drawing.Point(3, 477); + this.crcLabel.Name = "crcLabel"; + this.crcLabel.Size = new System.Drawing.Size(41, 13); + this.crcLabel.TabIndex = 12; + this.crcLabel.Text = "CRC32"; + // + // gameSystemBox + // + this.gameSystemBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.gameSystemBox.FormattingEnabled = true; + this.gameSystemBox.Location = new System.Drawing.Point(80, 4); + this.gameSystemBox.Name = "gameSystemBox"; + this.gameSystemBox.Size = new System.Drawing.Size(121, 21); + this.gameSystemBox.TabIndex = 10; + // + // systemLabel + // + this.systemLabel.AutoSize = true; + this.systemLabel.Location = new System.Drawing.Point(3, 3); + this.systemLabel.Name = "systemLabel"; + this.systemLabel.Size = new System.Drawing.Size(41, 13); + this.systemLabel.TabIndex = 11; + this.systemLabel.Text = "System"; + // + // nameBox + // + this.nameBox.Location = new System.Drawing.Point(80, 27); + this.nameBox.Name = "nameBox"; + this.nameBox.Size = new System.Drawing.Size(233, 20); + this.nameBox.TabIndex = 11; + // + // nameLabel + // + this.nameLabel.AutoSize = true; + this.nameLabel.Location = new System.Drawing.Point(3, 27); + this.nameLabel.Name = "nameLabel"; + this.nameLabel.Size = new System.Drawing.Size(35, 13); + this.nameLabel.TabIndex = 0; + this.nameLabel.Text = "Name"; + // + // mainMenuStrip + // + this.mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.databaseToolStripMenuItem}); + this.mainMenuStrip.Location = new System.Drawing.Point(0, 0); + this.mainMenuStrip.Name = "mainMenuStrip"; + this.mainMenuStrip.Size = new System.Drawing.Size(963, 24); + this.mainMenuStrip.TabIndex = 2; + this.mainMenuStrip.Text = "menuStrip2"; + // + // databaseToolStripMenuItem + // + this.databaseToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.directoryScanToolStripMenuItem, + this.cleanupDBToolStripMenuItem}); + this.databaseToolStripMenuItem.Name = "databaseToolStripMenuItem"; + this.databaseToolStripMenuItem.Size = new System.Drawing.Size(67, 20); + this.databaseToolStripMenuItem.Text = "Database"; + // + // directoryScanToolStripMenuItem + // + this.directoryScanToolStripMenuItem.Name = "directoryScanToolStripMenuItem"; + this.directoryScanToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.directoryScanToolStripMenuItem.Text = "Directory Scan"; + this.directoryScanToolStripMenuItem.Click += new System.EventHandler(this.directoryScanToolStripMenuItem_Click); + // + // publisherBox + // + this.publisherBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + this.publisherBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + this.publisherBox.Location = new System.Drawing.Point(80, 244); + this.publisherBox.Name = "publisherBox"; + this.publisherBox.Size = new System.Drawing.Size(194, 20); + this.publisherBox.TabIndex = 32; + // + // publisherLabel + // + this.publisherLabel.AutoSize = true; + this.publisherLabel.Location = new System.Drawing.Point(3, 244); + this.publisherLabel.Name = "publisherLabel"; + this.publisherLabel.Size = new System.Drawing.Size(50, 13); + this.publisherLabel.TabIndex = 33; + this.publisherLabel.Text = "Publisher"; + // + // classificationBox + // + this.classificationBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.classificationBox.FormattingEnabled = true; + this.classificationBox.Items.AddRange(new object[] { + "Licensed", + "Unlicensed", + "Homebrew", + "Firmware"}); + this.classificationBox.Location = new System.Drawing.Point(80, 271); + this.classificationBox.Name = "classificationBox"; + this.classificationBox.Size = new System.Drawing.Size(121, 21); + this.classificationBox.TabIndex = 34; + // + // classificationLabel + // + this.classificationLabel.AutoSize = true; + this.classificationLabel.Location = new System.Drawing.Point(3, 271); + this.classificationLabel.Name = "classificationLabel"; + this.classificationLabel.Size = new System.Drawing.Size(32, 13); + this.classificationLabel.TabIndex = 35; + this.classificationLabel.Text = "Class"; + // + // releaseDateBox + // + this.releaseDateBox.Location = new System.Drawing.Point(80, 299); + this.releaseDateBox.Name = "releaseDateBox"; + this.releaseDateBox.Size = new System.Drawing.Size(100, 20); + this.releaseDateBox.TabIndex = 36; + // + // releaseDateLabel + // + this.releaseDateLabel.AutoSize = true; + this.releaseDateLabel.Location = new System.Drawing.Point(3, 299); + this.releaseDateLabel.Name = "releaseDateLabel"; + this.releaseDateLabel.Size = new System.Drawing.Size(48, 13); + this.releaseDateLabel.TabIndex = 37; + this.releaseDateLabel.Text = "Rls Date"; + // + // playersLabel + // + this.playersLabel.AutoSize = true; + this.playersLabel.Location = new System.Drawing.Point(3, 326); + this.playersLabel.Name = "playersLabel"; + this.playersLabel.Size = new System.Drawing.Size(41, 13); + this.playersLabel.TabIndex = 39; + this.playersLabel.Text = "Players"; + // + // catalogBox + // + this.catalogBox.Location = new System.Drawing.Point(80, 354); + this.catalogBox.Name = "catalogBox"; + this.catalogBox.Size = new System.Drawing.Size(194, 20); + this.catalogBox.TabIndex = 40; + // + // catalogLabel + // + this.catalogLabel.AutoSize = true; + this.catalogLabel.Location = new System.Drawing.Point(3, 354); + this.catalogLabel.Name = "catalogLabel"; + this.catalogLabel.Size = new System.Drawing.Size(43, 13); + this.catalogLabel.TabIndex = 41; + this.catalogLabel.Text = "Catalog"; + // + // playersBox + // + this.playersBox.AutoCompleteCustomSource.AddRange(new string[] { + "1 Player", + "2 Players Alternating", + "2 Players Cooperative", + "2 Players Versus"}); + this.playersBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + this.playersBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + this.playersBox.Location = new System.Drawing.Point(80, 326); + this.playersBox.Name = "playersBox"; + this.playersBox.Size = new System.Drawing.Size(194, 20); + this.playersBox.TabIndex = 38; + // + // saveButton + // + this.saveButton.Location = new System.Drawing.Point(6, 556); + this.saveButton.Name = "saveButton"; + this.saveButton.Size = new System.Drawing.Size(75, 23); + this.saveButton.TabIndex = 46; + this.saveButton.Text = "&Save"; + this.saveButton.UseVisualStyleBackColor = true; + this.saveButton.Click += new System.EventHandler(this.saveButton_Click); + // + // cancelButton + // + this.cancelButton.Location = new System.Drawing.Point(125, 556); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 48; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // cleanupDBToolStripMenuItem + // + this.cleanupDBToolStripMenuItem.Name = "cleanupDBToolStripMenuItem"; + this.cleanupDBToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.cleanupDBToolStripMenuItem.Text = "Cleanup DB"; + this.cleanupDBToolStripMenuItem.Click += new System.EventHandler(this.cleanupDBToolStripMenuItem_Click); + // + // altNamesBox + // + this.altNamesBox.Location = new System.Drawing.Point(80, 381); + this.altNamesBox.Name = "altNamesBox"; + this.altNamesBox.Size = new System.Drawing.Size(296, 20); + this.altNamesBox.TabIndex = 42; + // + // altNamesLabel + // + this.altNamesLabel.AutoSize = true; + this.altNamesLabel.Location = new System.Drawing.Point(3, 381); + this.altNamesLabel.Name = "altNamesLabel"; + this.altNamesLabel.Size = new System.Drawing.Size(55, 13); + this.altNamesLabel.TabIndex = 46; + this.altNamesLabel.Text = "Alt Names"; + // + // notesBox + // + this.notesBox.Location = new System.Drawing.Point(80, 408); + this.notesBox.Multiline = true; + this.notesBox.Name = "notesBox"; + this.notesBox.Size = new System.Drawing.Size(296, 61); + this.notesBox.TabIndex = 44; + // + // notesLabel + // + this.notesLabel.AutoSize = true; + this.notesLabel.Location = new System.Drawing.Point(3, 408); + this.notesLabel.Name = "notesLabel"; + this.notesLabel.Size = new System.Drawing.Size(35, 13); + this.notesLabel.TabIndex = 48; + this.notesLabel.Text = "Notes"; + // + // DBMan_MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(963, 642); + this.Controls.Add(this.splitContainer1); + this.Controls.Add(this.filterPanel); + this.Controls.Add(this.mainMenuStrip); + this.KeyPreview = true; + this.MainMenuStrip = this.menuStrip1; + this.Name = "DBMan_MainForm"; + this.Text = "Bizhawk DBMan"; + this.filterPanel.ResumeLayout(false); + this.filterPanel.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.detailPanel.ResumeLayout(false); + this.detailPanel.PerformLayout(); + this.mainMenuStrip.ResumeLayout(false); + this.mainMenuStrip.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel filterPanel; + private System.Windows.Forms.Label whereLabel; + private System.Windows.Forms.ComboBox systemBox; + private System.Windows.Forms.TextBox whereBox; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.ListView romListView; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.MenuStrip mainMenuStrip; + private System.Windows.Forms.ToolStripMenuItem databaseToolStripMenuItem; + private System.Windows.Forms.Panel detailPanel; + private System.Windows.Forms.ToolStripMenuItem directoryScanToolStripMenuItem; + private System.Windows.Forms.ComboBox gameSystemBox; + private System.Windows.Forms.Label systemLabel; + private System.Windows.Forms.TextBox nameBox; + private System.Windows.Forms.Label nameLabel; + private System.Windows.Forms.ColumnHeader romListColumnHeader1; + private System.Windows.Forms.ColumnHeader romListColumnHeader2; + private System.Windows.Forms.ColumnHeader romListColumnHeader3; + private System.Windows.Forms.ColumnHeader romListColumnHeader4; + private System.Windows.Forms.ColumnHeader romListColumnHeader5; + private System.Windows.Forms.TextBox crcBox; + private System.Windows.Forms.Label sha1Label; + private System.Windows.Forms.Label md5Label; + private System.Windows.Forms.Label crcLabel; + private System.Windows.Forms.TextBox sha1Box; + private System.Windows.Forms.TextBox md5Box; + private System.Windows.Forms.Label regionLabel; + private System.Windows.Forms.TextBox regionBox; + private System.Windows.Forms.Label versionLabel; + private System.Windows.Forms.TextBox versionBox; + private System.Windows.Forms.Label romMetaLabel; + private System.Windows.Forms.TextBox romMetaBox; + private System.Windows.Forms.Label gameMetaLabel; + private System.Windows.Forms.TextBox gameMetaBox; + private System.Windows.Forms.TextBox tagsBox; + private System.Windows.Forms.Label romStatusLabel; + private System.Windows.Forms.ComboBox romStatusBox; + private System.Windows.Forms.Label tagsLabel; + private System.Windows.Forms.Label developerLabel; + private System.Windows.Forms.TextBox developerBox; + private System.Windows.Forms.Label classificationLabel; + private System.Windows.Forms.ComboBox classificationBox; + private System.Windows.Forms.Label publisherLabel; + private System.Windows.Forms.TextBox publisherBox; + private System.Windows.Forms.Label releaseDateLabel; + private System.Windows.Forms.TextBox releaseDateBox; + private System.Windows.Forms.Label playersLabel; + private System.Windows.Forms.Label catalogLabel; + private System.Windows.Forms.TextBox catalogBox; + private System.Windows.Forms.TextBox playersBox; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button saveButton; + private System.Windows.Forms.ToolStripMenuItem cleanupDBToolStripMenuItem; + private System.Windows.Forms.Label altNamesLabel; + private System.Windows.Forms.TextBox altNamesBox; + private System.Windows.Forms.Label notesLabel; + private System.Windows.Forms.TextBox notesBox; + + } +} + diff --git a/BizHawk.Client.DBMan/DBMan_MainForm.cs b/BizHawk.Client.DBMan/DBMan_MainForm.cs new file mode 100644 index 0000000000..2e63077903 --- /dev/null +++ b/BizHawk.Client.DBMan/DBMan_MainForm.cs @@ -0,0 +1,271 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace BizHawk.Client.DBMan +{ + public partial class DBMan_MainForm : Form + { + string[] Systems = { "SMS", "GG", "SG", "PCE", "PCECD", "SGX", "NES", "GEN" }; + Rom SelectedRom; + + public DBMan_MainForm() + { + InitializeComponent(); + + nameBox.GotFocus += (o, e) => { nameBox.SelectionLength = 0; nameBox.SelectionStart = nameBox.Text.Length; }; + regionBox.GotFocus += (o, e) => { regionBox.SelectionLength = 0; regionBox.SelectionStart = versionBox.Text.Length; }; + versionBox.GotFocus += (o, e) => { versionBox.SelectionLength = 0; versionBox.SelectionStart = versionBox.Text.Length; }; + gameMetaBox.GotFocus += (o, e) => { gameMetaBox.SelectionLength = 0; gameMetaBox.SelectionStart = gameMetaBox.Text.Length; }; + romMetaBox.GotFocus += (o, e) => { romMetaBox.SelectionLength = 0; romMetaBox.SelectionStart = romMetaBox.Text.Length; }; + tagsBox.GotFocus += (o, e) => { tagsBox.SelectionLength = 0; tagsBox.SelectionStart = tagsBox.Text.Length; }; + developerBox.GotFocus += (o, e) => { developerBox.SelectionLength = 0; developerBox.SelectionStart = developerBox.Text.Length; }; + publisherBox.GotFocus += (o, e) => { publisherBox.SelectionLength = 0; publisherBox.SelectionStart = publisherBox.Text.Length; }; + releaseDateBox.GotFocus += (o, e) => { releaseDateBox.SelectionLength = 0; releaseDateBox.SelectionStart = releaseDateBox.Text.Length; }; + playersBox.GotFocus += (o, e) => { playersBox.SelectionLength = 0; playersBox.SelectionStart = playersBox.Text.Length; }; + catalogBox.GotFocus += (o, e) => { catalogBox.SelectionLength = 0; catalogBox.SelectionStart = catalogBox.Text.Length; }; + altNamesBox.GotFocus += (o, e) => { altNamesBox.SelectionLength = 0; altNamesBox.SelectionStart = altNamesBox.Text.Length; }; + notesBox.GotFocus += (o, e) => { notesBox.SelectionLength = 0; notesBox.SelectionStart = notesBox.Text.Length; }; + + configSystemBox(); + loadRomsForSelectedSystem(); + } + + void configSystemBox() + { + systemBox.Items.AddRange(Systems); + systemBox.Items.Add("Unassigned"); + systemBox.SelectedIndex = 0; + gameSystemBox.Items.AddRange(Systems); + gameSystemBox.Items.Add("Unassigned"); + } + + void loadRomsForSelectedSystem() + { + DB.LoadDbForSystem(systemBox.SelectedItem.ToString()); + var names = DB.GetDeveloperPublisherNames().ToArray(); + + romListView.Items.Clear(); + foreach (var rom in DB.Roms) + { + var lvi = new ListViewItem(new string[] { rom.Name, rom.Region, rom.VersionTags, rom.CombinedMetaData, rom.Game.Tags }); + lvi.Tag = rom; + romListView.Items.Add(lvi); + } + detailPanel.Visible = false; + SelectedRom = null; + + developerBox.AutoCompleteCustomSource.Clear(); + developerBox.AutoCompleteCustomSource.AddRange(names); + publisherBox.AutoCompleteCustomSource.Clear(); + publisherBox.AutoCompleteCustomSource.AddRange(names); + } + + void systemBox_SelectedIndexChanged(object sender, EventArgs e) + { + loadRomsForSelectedSystem(); + } + + void directoryScanToolStripMenuItem_Click(object sender, EventArgs e) + { + var ds = new FolderBrowserDialog { ShowNewFolderButton = false }; + var result = ds.ShowDialog(); + if (result == DialogResult.OK) + { + var infos = DirectoryScan.GetRomInfos(ds.SelectedPath); + DirectoryScan.MergeRomInfosWithDatabase(infos); + MessageBox.Show("Directory Import complete!"); + } + } + + bool RomChanged; + + void selectedRomChanged(object sender, EventArgs e) + { + if (RomChangesMade()) + { + var result = MessageBox.Show("Save changes?", "Save or Cancel Changes", MessageBoxButtons.YesNo); + if (result == DialogResult.Yes) + saveButton_Click(null, null); + SelectedRom = null; + } + + RomChanged = true; + } + + void selectedRomMouseUp(object sender, MouseEventArgs e) + { + if (RomChanged == false) return; + RomChanged = false; + + if (romListView.SelectedItems.Count == 0) + { + detailPanel.Visible = false; + return; + } + + var rom = (Rom)romListView.SelectedItems[0].Tag; + SelectedRom = rom; + + gameSystemBox.Text = rom.System; + nameBox.Text = rom.Name; + crcBox.Text = rom.CRC32; + md5Box.Text = rom.MD5; + sha1Box.Text = rom.SHA1; + regionBox.Text = rom.Region; + versionBox.Text = rom.VersionTags; + gameMetaBox.Text = rom.Game.GameMetadata; + romMetaBox.Text = rom.RomMetadata; + tagsBox.Text = rom.Game.Tags; + romStatusBox.Text = rom.RomStatus; + developerBox.Text = rom.Game.Developer; + publisherBox.Text = rom.Game.Publisher; + classificationBox.Text = rom.Game.Classification; + releaseDateBox.Text = rom.Game.ReleaseDate; + playersBox.Text = rom.Game.Players; + catalogBox.Text = rom.Catalog; + altNamesBox.Text = rom.Game.AltNames; + notesBox.Text = rom.Game.Notes; + + detailPanel.Visible = true; + // nameBox.Focus(); + } + + void cancelButton_Click(object sender, EventArgs e) + { + RomChanged = true; + selectedRomMouseUp(null, null); + } + + void saveButton_Click(object sender, EventArgs e) + { + // Check if any changes were made + if (RomChangesMade() == false) + return; + + int saveMode = 0; + string origSystem = SelectedRom.System; + string origName = SelectedRom.Name; + + // Did we change System or Name? + if (KeyChangesMade()) + { + var rslt = MessageBox.Show("Change all instances of this system/name?\n\nClicking Yes will change all roms to point to the new game info.\nClicking No will create a new Game instance.", "Confirm game change action", MessageBoxButtons.YesNo); + saveMode = (rslt == DialogResult.Yes) ? 1 : 2; + } + + // Actually save the stuff + SelectedRom.System = fmt(gameSystemBox.Text); + SelectedRom.Name = fmt(nameBox.Text); + SelectedRom.Region = fmt(regionBox.Text); + SelectedRom.VersionTags = fmt(versionBox.Text); + SelectedRom.Game.GameMetadata = fmt(gameMetaBox.Text); + SelectedRom.RomMetadata = fmt(romMetaBox.Text); + SelectedRom.Game.Tags = fmt(tagsBox.Text); + SelectedRom.RomStatus = fmt(romStatusBox.Text); + SelectedRom.Game.Developer = fmt(developerBox.Text); + SelectedRom.Game.Publisher = fmt(publisherBox.Text); + SelectedRom.Game.Classification = fmt(classificationBox.Text); + SelectedRom.Game.ReleaseDate = fmt(releaseDateBox.Text); + SelectedRom.Game.Players = fmt(playersBox.Text); + SelectedRom.Catalog = fmt(catalogBox.Text); + SelectedRom.Game.AltNames = fmt(altNamesBox.Text); + SelectedRom.Game.Notes = fmt(notesBox.Text); + + if (saveMode == 0) DB.SaveRom(SelectedRom); + if (saveMode == 1) DB.SaveRom1(SelectedRom, origSystem, origName); + if (saveMode == 2) DB.SaveRom2(SelectedRom); + + + if (romListView.SelectedItems.Count > 0) + { + // Update the side listing + var romListItem = (ListViewItem)romListView.SelectedItems[0]; + romListItem.SubItems[0] = new ListViewItem.ListViewSubItem(romListItem, SelectedRom.Name); + romListItem.SubItems[1] = new ListViewItem.ListViewSubItem(romListItem, SelectedRom.Region); + romListItem.SubItems[2] = new ListViewItem.ListViewSubItem(romListItem, SelectedRom.VersionTags); + romListItem.SubItems[3] = new ListViewItem.ListViewSubItem(romListItem, SelectedRom.CombinedMetaData); + romListItem.SubItems[4] = new ListViewItem.ListViewSubItem(romListItem, SelectedRom.Game.Tags); + } + + if (saveMode > 0) loadRomsForSelectedSystem(); + } + + bool RomChangesMade() + { + if (SelectedRom == null) + return false; + + if (!streq(SelectedRom.System, gameSystemBox.Text)) return true; + if (!streq(SelectedRom.Name, nameBox.Text)) return true; + if (!streq(SelectedRom.Region, regionBox.Text)) return true; + if (!streq(SelectedRom.VersionTags, versionBox.Text)) return true; + if (!streq(SelectedRom.Game.GameMetadata, gameMetaBox.Text)) return true; + if (!streq(SelectedRom.RomMetadata, romMetaBox.Text)) return true; + if (!streq(SelectedRom.Game.Tags, tagsBox.Text)) return true; + if (!streq(SelectedRom.RomStatus, romStatusBox.Text)) return true; + if (!streq(SelectedRom.Game.Developer, developerBox.Text)) return true; + if (!streq(SelectedRom.Game.Publisher, publisherBox.Text)) return true; + if (!streq(SelectedRom.Game.Classification, classificationBox.Text)) return true; + if (!streq(SelectedRom.Game.ReleaseDate, releaseDateBox.Text)) return true; + if (!streq(SelectedRom.Game.Players, playersBox.Text)) return true; + if (!streq(SelectedRom.Catalog, catalogBox.Text)) return true; + if (!streq(SelectedRom.Game.AltNames, altNamesBox.Text)) return true; + if (!streq(SelectedRom.Game.Notes, notesBox.Text)) return true; + + return false; + } + + bool KeyChangesMade() + { + if (SelectedRom == null) + return false; + + if (!streq(SelectedRom.System, gameSystemBox.Text)) return true; + if (!streq(SelectedRom.Name, nameBox.Text)) return true; + return false; + } + + + static bool streq(string s1, string s2) + { + if (string.IsNullOrWhiteSpace(s1) && string.IsNullOrWhiteSpace(s2)) return true; + if (s1 == null || s2 == null) return false; + return s1.Trim() == s2.Trim(); + } + + static string fmt(string s) + { + var trimmed = s.Trim(); + if (trimmed.Length == 0) + return null; + return trimmed; + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == (Keys.F5)) + { + loadRomsForSelectedSystem(); + return true; + } + if (keyData == (Keys.S | Keys.Control) && SelectedRom != null) + { + saveButton_Click(null, null); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + void cleanupDBToolStripMenuItem_Click(object sender, EventArgs e) + { + DB.Cleanup(); + MessageBox.Show("Orphaned GAME records deleted and Sqlite VACUUM performed."); + } + } +} \ No newline at end of file diff --git a/BizHawk.Client.DBMan/DBMan_MainForm.resx b/BizHawk.Client.DBMan/DBMan_MainForm.resx new file mode 100644 index 0000000000..cdc70987cf --- /dev/null +++ b/BizHawk.Client.DBMan/DBMan_MainForm.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 17, 17 + + + 132, 17 + + \ No newline at end of file diff --git a/BizHawk.Client.DBMan/DirectoryScan.cs b/BizHawk.Client.DBMan/DirectoryScan.cs new file mode 100644 index 0000000000..ce40ef092f --- /dev/null +++ b/BizHawk.Client.DBMan/DirectoryScan.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using System.IO; +using BizHawk.Common; +using Community.CsharpSqlite.SQLiteClient; + +namespace BizHawk.Client.DBMan +{ + public static class DirectoryScan + { + public static List GetRomInfos(string path) + { + var dirInfo = new DirectoryInfo(path); + var files = dirInfo.GetFiles("*", SearchOption.AllDirectories); + var romInfos = new List(); + + foreach (var f in files) + { + if (IsRomFile(f.Extension, f.Length) == false) + continue; + romInfos.Add(RomHasher.Generate(f.FullName)); + } + + return romInfos; + } + + const long BiggestBinToHash = 16 * 1024 * 1024; + + public static bool IsRomFile(string ext, long size) + { + if (string.IsNullOrEmpty(ext) || ext.Length <= 1) + return false; + + ext = ext.Substring(1).ToLowerInvariant(); + if (ext.In("cue", "iso", "nes", "unf", "fds", "sfc", "smc", "sms", "gg", "sg", "pce", "sgx", "gb", "gbc", "gba", "gen", "md", "smd", "a26", "a78", "col", "z64", "v64", "n64")) + return true; + + // the logic here is related to cue/bin cd images. + // when we see a .cue file, we will hash the cd image including the bin. + // so we don't really want to hash the whole bin a second time. + // however, there are also non-cdimage roms with BIN extension. + // hopefully this differentiates them. It may have to be tweaked as systems are added. + + if (ext == "bin" && size < BiggestBinToHash) + return true; + + return false; + } + + // ======================================================================================== + + public static void MergeRomInfosWithDatabase(IList roms) + { + + foreach (var rom in roms) + { + if (RomInDatabase(rom.MD5) == false) + { + InsertRom(rom); + + if (GameInDatabase(rom) == false) + InsertGame(rom); + } + } + } + + static bool RomInDatabase(string md5) + { + using (var cmd = DB.Con.CreateCommand()) + { + cmd.CommandText = "SELECT rom_id FROM rom WHERE md5 = @md5"; + cmd.Parameters.Add(new SqliteParameter("@md5", md5)); + var result = cmd.ExecuteScalar(); + return result != null; + } + } + + static bool GameInDatabase(InitialRomInfo rom) + { + using (var cmd = DB.Con.CreateCommand()) + { + cmd.CommandText = "SELECT game_id FROM game WHERE system = @System and name = @Name"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.GuessedSystem)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + var result = cmd.ExecuteScalar(); + return result != null; + } + } + + static void InsertRom(InitialRomInfo rom) + { + using (var cmd = DB.Con.CreateCommand()) + { + cmd.CommandText = + "INSERT INTO rom (crc32, md5, sha1, system, name, region, version_tags) "+ + "VALUES (@crc32, @md5, @sha1, @System, @Name, @Region, @VersionTags)"; + cmd.Parameters.Add(new SqliteParameter("@crc32", rom.CRC32)); + cmd.Parameters.Add(new SqliteParameter("@md5", rom.MD5)); + cmd.Parameters.Add(new SqliteParameter("@sha1", rom.SHA1)); + cmd.Parameters.Add(new SqliteParameter("@System", rom.GuessedSystem)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.Parameters.Add(new SqliteParameter("@Region", rom.GuessedRegion)); + cmd.Parameters.Add(new SqliteParameter("@VersionTags", rom.VersionTags)); + cmd.ExecuteNonQuery(); + } + } + + static void InsertGame(InitialRomInfo rom) + { + using (var cmd = DB.Con.CreateCommand()) + { + cmd.CommandText = "INSERT INTO game (system, name) VALUES (@System, @Name)"; + cmd.Parameters.Add(new SqliteParameter("@System", rom.GuessedSystem)); + cmd.Parameters.Add(new SqliteParameter("@Name", rom.Name)); + cmd.ExecuteNonQuery(); + } + } + } +} diff --git a/BizHawk.Client.DBMan/Program.cs b/BizHawk.Client.DBMan/Program.cs new file mode 100644 index 0000000000..8da6e3f568 --- /dev/null +++ b/BizHawk.Client.DBMan/Program.cs @@ -0,0 +1,36 @@ +using System; +using System.Windows.Forms; +using Community.CsharpSqlite.SQLiteClient; + +namespace BizHawk.Client.DBMan +{ + internal static class Program + { + [STAThread] + static void Main() + { + try + { + InitDB(); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new DBMan_MainForm()); + } + catch (Exception e) + { + MessageBox.Show(e.ToString()); + } + finally + { + if (DB.Con != null) DB.Con.Dispose(); + } + } + + static void InitDB() + { + DB.Con = new SqliteConnection(); + DB.Con.ConnectionString = @"Version=3,uri=file://game.db"; + DB.Con.Open(); + } + } +} diff --git a/BizHawk.Client.DBMan/Properties/AssemblyInfo.cs b/BizHawk.Client.DBMan/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..38798300a9 --- /dev/null +++ b/BizHawk.Client.DBMan/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BizHawk.Client.DBMan")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BizHawk.Client.DBMan")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("58cef5c3-fb2d-4d02-8f02-46a53c1c49cf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BizHawk.Client.DBMan/Properties/Resources.Designer.cs b/BizHawk.Client.DBMan/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..2f2ae431a5 --- /dev/null +++ b/BizHawk.Client.DBMan/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18034 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BizHawk.Client.DBMan.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BizHawk.Client.DBMan.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/BizHawk.Client.DBMan/Properties/Resources.resx b/BizHawk.Client.DBMan/Properties/Resources.resx new file mode 100644 index 0000000000..ffecec851a --- /dev/null +++ b/BizHawk.Client.DBMan/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BizHawk.Client.DBMan/Properties/Settings.Designer.cs b/BizHawk.Client.DBMan/Properties/Settings.Designer.cs new file mode 100644 index 0000000000..fb22014f1e --- /dev/null +++ b/BizHawk.Client.DBMan/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18034 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BizHawk.Client.DBMan.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/BizHawk.Client.DBMan/Properties/Settings.settings b/BizHawk.Client.DBMan/Properties/Settings.settings new file mode 100644 index 0000000000..abf36c5d3d --- /dev/null +++ b/BizHawk.Client.DBMan/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/BizHawk.Client.DBMan/RomHasher.cs b/BizHawk.Client.DBMan/RomHasher.cs new file mode 100644 index 0000000000..40a6c471bb --- /dev/null +++ b/BizHawk.Client.DBMan/RomHasher.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.DiscSystem; + +namespace BizHawk.Client.DBMan +{ + public class InitialRomInfo + { + public string FileName; + public string Name; + public string VersionTags; + public string GuessedSystem; + public string GuessedRegion; + public string CRC32; + public string MD5; + public string SHA1; + + public override string ToString() + { + return FileName; + } + } + + public static class RomHasher + { + public static InitialRomInfo Generate(string file) + { + //if (isDiscImage(file)) +// return HashDiscImage(file); + + return GenerateRomHashDirect(file, File.ReadAllBytes(file)); + } + + static char[] modifierStartChars = { '(', '[' }; + static InitialRomInfo GenerateRomHashDirect(string file, byte[] filebytes) + { + var info = new InitialRomInfo(); + var fileInfo = new FileInfo(file); + string ext = fileInfo.Extension.ToLowerInvariant().Replace(".", ""); + info.FileName = fileInfo.Name; + + // Parse the filename to guess things about the rom + var name = Path.GetFileNameWithoutExtension(fileInfo.Name); + if (name.StartsWith("[BIOS] ")) + name = name.Replace("[BIOS] ","") + " [BIOS]"; + + string modifiers = ""; + int modIndex = name.IndexOfAny(modifierStartChars); + if (modIndex > 0) + { + modifiers = name.Substring(modIndex); + name = name.Substring(0, modIndex); + } + info.Name = name.Trim(); + + // parse out modifiers + var mods = new List(); + modifiers = modifiers.Replace(")", ";").Replace("]",";"); + modifiers = modifiers.Replace("(", "").Replace("[", ""); + var m_ = modifiers.Split(';'); + foreach (var mi in m_) + { + var m = mi.Trim(); + if (m.Length == 0) continue; + mods.Add(m); + } + + info.VersionTags = ""; + foreach (var mi in mods) + { + if (info.VersionTags.Length != 0) + info.VersionTags += ";"; + + switch (mi.ToLower()) + { + case "j": + case "jp": + case "jpn": + case "japan": + info.GuessedRegion = "Japan"; + break; + case "usa": + case "us": + case "u": + info.GuessedRegion = "USA"; + break; + case "europe": + case "eur": + case "e": + info.GuessedRegion = "Europe"; + break; + case "world": + case "w": + info.GuessedRegion = "World"; + break; + case "korea": + case "kr": + case "k": + info.GuessedRegion = "Korea"; + break; + case "brazil": + case "br": + info.GuessedRegion = "Brazil"; + break; + case "taiwan": + case "tw": + info.GuessedRegion = "Taiwan"; + break; + case "usa, europe": + info.GuessedRegion = "USA;Europe"; + break; + case "japan, europe": + info.GuessedRegion = "Europe;Japan"; + break; + case "japan, usa": + info.GuessedRegion = "USA;Japan"; + break; + + default: + info.VersionTags += mi; + break; + } + } + + // transform binary to canonical binary representation (de-header/de-stripe/de-swap) + byte[] romBytes = filebytes; + switch (ext) + { + case "sms": + case "gg": + case "sg": + case "pce": + case "sgx": + romBytes = MaybeStripHeader512(filebytes); + break; + + case "smd": + if (filebytes.Length % 1024 == 512) + System.Windows.Forms.MessageBox.Show("derp"); + romBytes = DeInterleaveSMD(filebytes); + break; + + case "z64": + case "n64": + case "v64": + throw new NotImplementedException("n64 demutate not done"); + } + + // guess system + switch (ext) + { + case "sms": info.GuessedSystem = "SMS"; break; + case "gg": info.GuessedSystem = "GG"; break; + case "sg": info.GuessedSystem = "SG"; break; + case "pce": info.GuessedSystem = "PCE"; break; + case "sgx": info.GuessedSystem = "SGX"; break; + case "smd": + case "gen": info.GuessedSystem = "GEN"; break; + case "nes": info.GuessedSystem = "NES"; break; + default: info.GuessedSystem = "Unknown"; break; + } + + // Perform hashing + info.CRC32 = Hash_CRC32(romBytes); + info.MD5 = Hash_MD5(romBytes); + info.SHA1 = Hash_SHA1(romBytes); + + return info; + } + + static string HashDiscImage(string file) + { + try + { + string ext = new FileInfo(file).Extension.ToLowerInvariant(); + using (var disc = ext == ".iso" ? Disc.FromIsoPath(file) : Disc.FromCuePath(file, new CueBinPrefs())) + { + return disc.GetHash(); + } + } + catch + { + return "Error Hashing Disc"; + } + } + + static string Hash_CRC32(byte[] data) + { + return string.Format("{0:X8}", CRC32.Calculate(data)); + } + + static string Hash_SHA1(byte[] data) + { + using (var sha1 = System.Security.Cryptography.SHA1.Create()) + { + sha1.TransformFinalBlock(data, 0, data.Length); + return BytesToHexString(sha1.Hash); + } + } + + static string Hash_MD5(byte[] data) + { + using (var md5 = System.Security.Cryptography.MD5.Create()) + { + md5.TransformFinalBlock(data, 0, data.Length); + return BytesToHexString(md5.Hash); + } + } + + static string BytesToHexString(byte[] bytes) + { + var sb = new StringBuilder(); + foreach (var b in bytes) + sb.AppendFormat("{0:X2}", b); + + return sb.ToString(); + } + + static byte[] MaybeStripHeader512(byte[] fileBytes) + { + if (fileBytes.Length % 1024 != 512) + return fileBytes; + + var romBytes = new byte[fileBytes.Length - 512]; + Array.Copy(fileBytes, 512, romBytes, 0, fileBytes.Length - 512); + return romBytes; + } + + static byte[] DeInterleaveSMD(byte[] source) + { + int size = source.Length; + if (size > 0x400000) + size = 0x400000; + + int pages = size / 0x4000; + var output = new byte[size]; + + for (int page = 0; page < pages; page++) + { + for (int i = 0; i < 0x2000; i++) + { + output[(page * 0x4000) + (i * 2) + 0] = source[(page * 0x4000) + 0x2000 + i]; + output[(page * 0x4000) + (i * 2) + 1] = source[(page * 0x4000) + 0x0000 + i]; + } + } + return output; + } + + static bool isDiscImage(string file) + { + var ext = new FileInfo(file).Extension.ToLowerInvariant(); + if (ext == ".cue" || ext == ".iso") + return true; + return false; + } + } +} \ No newline at end of file diff --git a/BizHawk.Client.DBMan/app.config b/BizHawk.Client.DBMan/app.config new file mode 100644 index 0000000000..cb2586beb1 --- /dev/null +++ b/BizHawk.Client.DBMan/app.config @@ -0,0 +1,3 @@ + + + diff --git a/BizHawk.sln b/BizHawk.sln index ce22cf98ba..275df03384 100644 --- a/BizHawk.sln +++ b/BizHawk.sln @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Bizware.BizwareGL", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Bizware.BizwareGL.OpenTK", "Bizware\BizHawk.Bizware.BizwareGL.OpenTK\BizHawk.Bizware.BizwareGL.OpenTK.csproj", "{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Client.DBMan", "BizHawk.Client.DBMan\BizHawk.Client.DBMan.csproj", "{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -145,6 +147,18 @@ Global {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Win32.ActiveCfg = Release|Any CPU {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x86.ActiveCfg = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x86.ActiveCfg = Debug|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Any CPU.Build.0 = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Win32.ActiveCfg = Release|Any CPU + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -153,6 +167,7 @@ Global {DD448B37-BA3F-4544-9754-5406E8094723} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {C4366030-6D03-424B-AE53-F4F43BB217C3} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {24A0AA3C-B25F-4197-B23D-476D6462DBA0} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {E1A23168-B571-411C-B360-2229E7225E0E} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} {F51946EA-827F-4D82-B841-1F2F6D060312} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} {197D4314-8A9F-49BA-977D-54ACEFAEB6BA} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} diff --git a/output/game.db b/output/game.db new file mode 100644 index 0000000000..95701bc8c4 Binary files /dev/null and b/output/game.db differ