diff --git a/BizHawk.Client.EmuHawk/LogWindow.Designer.cs b/BizHawk.Client.EmuHawk/LogWindow.Designer.cs index 11ab828da7..fe03b76c7a 100644 --- a/BizHawk.Client.EmuHawk/LogWindow.Designer.cs +++ b/BizHawk.Client.EmuHawk/LogWindow.Designer.cs @@ -33,6 +33,7 @@ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.buttonCopy = new System.Windows.Forms.Button(); this.buttonCopyAll = new System.Windows.Forms.Button(); + this.AddToGameDbBtn = new System.Windows.Forms.Button(); this.virtualListView1 = new BizHawk.Client.EmuHawk.VirtualListView(); this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tableLayoutPanel1.SuspendLayout(); @@ -43,7 +44,7 @@ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnClose.Location = new System.Drawing.Point(597, 3); this.btnClose.Name = "btnClose"; - this.btnClose.Size = new System.Drawing.Size(75, 23); + this.btnClose.Size = new System.Drawing.Size(75, 24); this.btnClose.TabIndex = 2; this.btnClose.Text = "Close"; this.btnClose.UseVisualStyleBackColor = true; @@ -53,7 +54,7 @@ // this.btnClear.Location = new System.Drawing.Point(3, 3); this.btnClear.Name = "btnClear"; - this.btnClear.Size = new System.Drawing.Size(75, 23); + this.btnClear.Size = new System.Drawing.Size(75, 24); this.btnClear.TabIndex = 1; this.btnClear.Text = "&Clear"; this.btnClear.UseVisualStyleBackColor = true; @@ -73,19 +74,20 @@ this.tableLayoutPanel1.Controls.Add(this.btnClose, 4, 0); this.tableLayoutPanel1.Controls.Add(this.buttonCopy, 1, 0); this.tableLayoutPanel1.Controls.Add(this.buttonCopyAll, 2, 0); + this.tableLayoutPanel1.Controls.Add(this.AddToGameDbBtn, 3, 0); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 368); + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 367); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 1; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(675, 29); + this.tableLayoutPanel1.Size = new System.Drawing.Size(675, 30); this.tableLayoutPanel1.TabIndex = 5; // // buttonCopy // this.buttonCopy.Location = new System.Drawing.Point(84, 3); this.buttonCopy.Name = "buttonCopy"; - this.buttonCopy.Size = new System.Drawing.Size(75, 23); + this.buttonCopy.Size = new System.Drawing.Size(75, 24); this.buttonCopy.TabIndex = 3; this.buttonCopy.Text = "Copy Sel."; this.buttonCopy.UseVisualStyleBackColor = true; @@ -95,12 +97,25 @@ // this.buttonCopyAll.Location = new System.Drawing.Point(165, 3); this.buttonCopyAll.Name = "buttonCopyAll"; - this.buttonCopyAll.Size = new System.Drawing.Size(75, 23); + this.buttonCopyAll.Size = new System.Drawing.Size(75, 24); this.buttonCopyAll.TabIndex = 4; this.buttonCopyAll.Text = "Copy All"; this.buttonCopyAll.UseVisualStyleBackColor = true; this.buttonCopyAll.Click += new System.EventHandler(this.buttonCopyAll_Click); // + // AddToGameDbBtn + // + this.AddToGameDbBtn.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.RetroQuestion; + this.AddToGameDbBtn.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.AddToGameDbBtn.Location = new System.Drawing.Point(246, 3); + this.AddToGameDbBtn.Name = "AddToGameDbBtn"; + this.AddToGameDbBtn.Size = new System.Drawing.Size(109, 24); + this.AddToGameDbBtn.TabIndex = 5; + this.AddToGameDbBtn.Text = "Add to database"; + this.AddToGameDbBtn.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.AddToGameDbBtn.UseVisualStyleBackColor = true; + this.AddToGameDbBtn.Click += new System.EventHandler(this.AddToGameDbBtn_Click); + // // virtualListView1 // this.virtualListView1.BlazingFast = false; @@ -114,7 +129,7 @@ this.virtualListView1.Name = "virtualListView1"; this.virtualListView1.SelectAllInProgress = false; this.virtualListView1.selectedItem = -1; - this.virtualListView1.Size = new System.Drawing.Size(675, 368); + this.virtualListView1.Size = new System.Drawing.Size(675, 367); this.virtualListView1.TabIndex = 8; this.virtualListView1.UseCompatibleStateImageBehavior = false; this.virtualListView1.View = System.Windows.Forms.View.Details; @@ -152,5 +167,6 @@ private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.Button buttonCopy; private System.Windows.Forms.Button buttonCopyAll; + private System.Windows.Forms.Button AddToGameDbBtn; } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/LogWindow.cs b/BizHawk.Client.EmuHawk/LogWindow.cs index 817d426e33..8e2dfdfc95 100644 --- a/BizHawk.Client.EmuHawk/LogWindow.cs +++ b/BizHawk.Client.EmuHawk/LogWindow.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Text; using System.Windows.Forms; +using BizHawk.Common; using BizHawk.Client.Common; +using BizHawk.Emulation.Common; //todo - perks - pause, copy to clipboard, backlog length limiting @@ -12,6 +15,8 @@ namespace BizHawk.Client.EmuHawk { public partial class LogWindow : Form { + //TODO: only show add to game db when this is a Rom details dialog + //Let user decide what type (instead of always adding it as a good dump) private readonly List Lines = new List(); public LogWindow() @@ -78,6 +83,8 @@ namespace BizHawk.Client.EmuHawk Size = new Size(Global.Config.LogWindowWidth, Global.Config.LogWindowHeight); } } + + HideShowGameDbButton(); } public void SaveConfigSettings() @@ -126,5 +133,21 @@ namespace BizHawk.Client.EmuHawk buttonCopy_Click(null, null); } } + + private void HideShowGameDbButton() + { + AddToGameDbBtn.Visible = ReflectionUtil.HasExposedMethod(Global.Emulator, "GenerateGameDbEntry") + && (Global.Game.Status == RomStatus.Unknown || Global.Game.Status == RomStatus.NotInDatabase); + } + + private void AddToGameDbBtn_Click(object sender, EventArgs e) + { + var entryObj = (CompactGameInfo)ReflectionUtil.InvokeMethod(Global.Emulator, "GenerateGameDbEntry", null); + var userDb = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb_user.txt"); + Global.Game.Status = entryObj.Status = RomStatus.GoodDump; //TODO: let user decide + Database.SaveDatabaseEntry(userDb, entryObj); + GlobalWin.MainForm.UpdateDumpIcon(); + HideShowGameDbButton(); + } } } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 9e3cf28c59..49531e5a04 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -1092,7 +1092,7 @@ namespace BizHawk.Client.EmuHawk HandleToggleLight(); } - private void UpdateDumpIcon() + public void UpdateDumpIcon() { DumpStatusButton.Image = Properties.Resources.Blank; DumpStatusButton.ToolTipText = string.Empty; diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index 943c018036..2de7a3c355 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -62,6 +62,7 @@ + diff --git a/BizHawk.Common/ReflectionUtil.cs b/BizHawk.Common/ReflectionUtil.cs new file mode 100644 index 0000000000..834025b6e0 --- /dev/null +++ b/BizHawk.Common/ReflectionUtil.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace BizHawk.Common +{ + /// + /// Reflection based helper methods + /// + public static class ReflectionUtil + { + /// + /// Takes an object and determines if it has methodName as a public method + /// + /// Returns whether or not the obj both contains the method name and the method is public + public static bool HasExposedMethod(object obj, string methodName) + { + var method = obj.GetType().GetMethod(methodName); + + if (method != null) + { + return method.IsPublic; + } + + return false; + } + + /// + /// Takes an object and invokes the method + /// The method must exist and be public + /// + /// The return value of the method, as an object. + /// If the method returns void, the return value is null + /// If the method does not exist or is not public, it returns null + /// + public static object InvokeMethod(object obj, string methodName, object[] args) + { + var method = obj.GetType().GetMethod(methodName); + if (method != null && method.IsPublic) + { + return method.Invoke(obj, args); + } + + return null; + } + } +} diff --git a/BizHawk.Emulation.Common/Database/Database.cs b/BizHawk.Emulation.Common/Database/Database.cs index 9fe1891fe7..6510129f01 100644 --- a/BizHawk.Emulation.Common/Database/Database.cs +++ b/BizHawk.Emulation.Common/Database/Database.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using System.Threading; - using BizHawk.Common; namespace BizHawk.Emulation.Common @@ -71,6 +71,57 @@ namespace BizHawk.Emulation.Common } } + public static void SaveDatabaseEntry(string path, CompactGameInfo gameInfo) + { + var sb = new StringBuilder(); + sb + .Append("sha1:") // TODO: how do we know it is sha1? + .Append(gameInfo.Hash) + .Append('\t'); + + switch (gameInfo.Status) + { + case RomStatus.BadDump: + sb.Append("B"); + break; + case RomStatus.TranslatedRom: + sb.Append("T"); + break; + case RomStatus.Overdump: + sb.Append("O"); + break; + case RomStatus.BIOS: + sb.Append("I"); + break; + case RomStatus.Homebrew: + sb.Append("D"); + break; + case RomStatus.Hack: + sb.Append("H"); + break; + case RomStatus.Unknown: + sb.Append("U"); + break; + } + + sb + .Append('\t') + .Append(gameInfo.Name) + .Append('\t') + .Append(gameInfo.System) + .Append('\t') + .Append(gameInfo.MetaData) + .Append(Environment.NewLine); + try + { + File.AppendAllText(path, sb.ToString()); + } + catch (Exception ex) + { + string blah = ex.ToString(); + } + } + public static void LoadDatabase(string path) { using (var reader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index 3417f08649..729842dbe3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; +using System.Linq; using BizHawk.Common; using BizHawk.Emulation.Common; @@ -130,6 +131,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 } }; + public CompactGameInfo GenerateGameDbEntry() + { + return new CompactGameInfo + { + Name = _game.Name, + System = "A26", + MetaData = "m=" + _mapper.GetType().ToString().Split('.').ToList().Last(), + Hash = Util.Hash_SHA1(Rom), + Region = _game.Region, + Status = RomStatus.Unknown + }; + } + public List> GetCpuFlagsAndRegisters() { return new List>