Extract disc hashing from Octoshock, clean it up, and add to Nymashock

This commit is contained in:
James Groom 2023-11-21 06:54:11 +00:00 committed by GitHub
parent dada959cfa
commit ca5dc1a6e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 62 deletions

View File

@ -1662,8 +1662,8 @@ namespace BizHawk.Client.EmuHawk
private void PsxHashDiscsMenuItem_Click(object sender, EventArgs e) private void PsxHashDiscsMenuItem_Click(object sender, EventArgs e)
{ {
if (Emulator is not Octoshock psx) return; if (Emulator is not IRedumpDiscChecksumInfo psx) return;
using PSXHashDiscs form = new(psx); using PSXHashDiscs form = new() { _psx = psx };
this.ShowDialogWithTempMute(form); this.ShowDialogWithTempMute(form);
} }

View File

@ -93,7 +93,6 @@
this.MaximizeBox = false; this.MaximizeBox = false;
this.MinimizeBox = false; this.MinimizeBox = false;
this.Name = "PSXHashDiscs"; this.Name = "PSXHashDiscs";
this.Text = "PSX Disc Hasher";
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();

View File

@ -1,18 +1,21 @@
using System; using System;
using System.Windows.Forms;
using BizHawk.Emulation.Cores.Sony.PSX; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class PSXHashDiscs : Form [SpecializedTool("Hash Discs")] // puts this in Nymashock's VSystem menu (the generic one), though when opened that way it's not modal
public partial class PSXHashDiscs : ToolFormBase
{ {
private readonly Octoshock _psx; [RequiredService]
public IRedumpDiscChecksumInfo _psx { get; set; }
public PSXHashDiscs(Octoshock psx) protected override string WindowTitleStatic { get; } = "PSX Disc Hasher";
public PSXHashDiscs()
{ {
_psx = psx;
InitializeComponent(); InitializeComponent();
btnClose.Click += (_, _) => Close();
} }
private void BtnHash_Click(object sender, EventArgs e) private void BtnHash_Click(object sender, EventArgs e)

View File

@ -12,4 +12,9 @@
/// </summary> /// </summary>
string? RomDetails { get; } string? RomDetails { get; }
} }
public interface IRedumpDiscChecksumInfo : IRomInfo
{
string CalculateDiscHashes();
}
} }

View File

@ -0,0 +1,57 @@
#nullable enable
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.DiscSystem;
namespace BizHawk.Emulation.Cores.Sony.PSX
{
internal static class DiscChecksumUtils
{
private static readonly ConditionalWeakTable<Disc, string> _redumpHashCache = new();
public static string CalculateDiscHashesImpl(IReadOnlyList<Disc> discs)
=> string.Join("\n", discs.Select(static disc =>
{
if (_redumpHashCache.TryGetValue(disc, out var hash)) return hash;
try
{
hash = $"{new DiscHasher(disc).Calculate_PSX_RedumpHash():X8} {disc.Name}";
}
catch
{
// ignored
return string.Empty;
}
_redumpHashCache.Add(disc, hash);
return hash;
}));
public static string GenQuickRomDetails(IReadOnlyList<IDiscAsset> discs)
{
static string DiscHashWarningText(string discHash)
{
var game = Database.CheckDatabase(discHash);
return game?.Status is null or RomStatus.BadDump or RomStatus.NotInDatabase or RomStatus.Overdump
? "Disc could not be identified as known-good. Look for a better rip."
: $@"Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{discHash}
Nonetheless it could be an unrecognized romhack or patched version.
According to redump.org, the ideal hash for entire disc is: CRC32:{game.GetStringValue("dh")}
The file you loaded hasn't been hashed entirely (it would take too long)
Compare it with the full hash calculated by the PSX menu's Hash Discs tool";
}
return discs.Count is 0
? "PSX exe"
: string.Join("\n", discs.SelectMany(static disc => new[]
{
Path.GetFileName(disc.DiscName),
DiscHashWarningText(new DiscHasher(disc.DiscData).Calculate_PSX_BizIDHash()),
"-------------------------",
}));
}
}
}

View File

@ -5,12 +5,17 @@ using BizHawk.Common;
using BizHawk.Common.StringExtensions; using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Waterbox; using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.Emulation.DiscSystem;
namespace BizHawk.Emulation.Cores.Sony.PSX namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
[PortedCore(CoreNames.Nymashock, "Mednafen Team", "1.29.0", "https://mednafen.github.io/releases/")] [PortedCore(CoreNames.Nymashock, "Mednafen Team", "1.29.0", "https://mednafen.github.io/releases/")]
public class Nymashock : NymaCore, IRegionable, ICycleTiming public class Nymashock : NymaCore, IRegionable, ICycleTiming, IRedumpDiscChecksumInfo
{ {
public string RomDetails { get; }
private readonly IReadOnlyList<Disc> _discs;
protected override void AddAxis( protected override void AddAxis(
ControllerDefinition ret, ControllerDefinition ret,
string name, string name,
@ -68,8 +73,16 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
DoInit<LibNymaCore>(lp, "shock.wbx", firmwares); DoInit<LibNymaCore>(lp, "shock.wbx", firmwares);
_cachedSettingsInfo ??= SettingsInfo.Clone(); _cachedSettingsInfo ??= SettingsInfo.Clone();
List<Disc> discs = new();
foreach (var disc in lp.Discs) discs.Add(disc.DiscData);
_discs = discs;
RomDetails = DiscChecksumUtils.GenQuickRomDetails(lp.Discs);
} }
public string CalculateDiscHashes()
=> DiscChecksumUtils.CalculateDiscHashesImpl(_discs);
protected override IDictionary<string, SettingOverride> SettingOverrides { get; } = new Dictionary<string, SettingOverride> protected override IDictionary<string, SettingOverride> SettingOverrides { get; } = new Dictionary<string, SettingOverride>
{ {
{ "psx.bios_jp", new() { Hide = true , Default = "$J" } }, // FIRMWARE: { "psx.bios_jp", new() { Hide = true , Default = "$J" } }, // FIRMWARE:

View File

@ -16,7 +16,6 @@ using System.Runtime.InteropServices;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -30,7 +29,9 @@ using BizHawk.Emulation.DiscSystem;
namespace BizHawk.Emulation.Cores.Sony.PSX namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
[PortedCore(CoreNames.Octoshock, "Mednafen Team")] [PortedCore(CoreNames.Octoshock, "Mednafen Team")]
public unsafe partial class Octoshock : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IDriveLight, ISettable<Octoshock.Settings, Octoshock.SyncSettings>, IRegionable, IInputPollable, IRomInfo public unsafe partial class Octoshock : IEmulator, IInputPollable, IRegionable, ISaveRam,
ISettable<Octoshock.Settings, Octoshock.SyncSettings>, ISoundProvider, IStatable, IVideoProvider,
IDriveLight, IRedumpDiscChecksumInfo
{ {
public Octoshock(CoreComm comm, PSF psf, Octoshock.Settings settings, Octoshock.SyncSettings syncSettings) public Octoshock(CoreComm comm, PSF psf, Octoshock.Settings settings, Octoshock.SyncSettings syncSettings)
{ {
@ -44,45 +45,15 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[CoreConstructor(VSystemID.Raw.PSX)] [CoreConstructor(VSystemID.Raw.PSX)]
public Octoshock(CoreLoadParameters<Octoshock.Settings, Octoshock.SyncSettings> lp) public Octoshock(CoreLoadParameters<Octoshock.Settings, Octoshock.SyncSettings> lp)
{ {
string romDetails;
if (lp.Discs.Count > 0)
{
string DiscHashWarningText(GameInfo game, string discHash)
{
if (game == null || game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
{
return "Disc could not be identified as known-good. Look for a better rip.";
}
else
{
return $"Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{discHash}\n"
+ "Nonetheless it could be an unrecognized romhack or patched version.\n"
+ $"According to redump.org, the ideal hash for entire disc is: CRC32:{game.GetStringValue("dh")}\n"
+ "The file you loaded hasn't been hashed entirely (it would take too long)\n"
+ "Compare it with the full hash calculated by the PSX menu's Hash Discs tool";
}
}
var sw = new StringWriter();
foreach (var d in lp.Discs)
{
var discHash = new DiscHasher(d.DiscData).Calculate_PSX_BizIDHash();
sw.WriteLine(Path.GetFileName(d.DiscName));
sw.WriteLine(DiscHashWarningText(Database.CheckDatabase(discHash), discHash));
sw.WriteLine("-------------------------");
}
romDetails = sw.ToString();
}
else
{
romDetails = "PSX exe";
}
Load( Load(
lp.Comm, lp.Comm,
lp.Discs.Select(d => d.DiscData).ToList(), lp.Discs.Select(d => d.DiscData).ToList(),
lp.Discs.Select(d => d.DiscName).ToList(), lp.Discs.Select(d => d.DiscName).ToList(),
lp.Roms.FirstOrDefault()?.RomData, lp.Settings, lp.SyncSettings, null, romDetails); lp.Roms.FirstOrDefault()?.RomData,
lp.Settings,
lp.SyncSettings,
null,
DiscChecksumUtils.GenQuickRomDetails(lp.Discs));
OctoshockDll.shock_PowerOn(psx); OctoshockDll.shock_PowerOn(psx);
} }
@ -498,21 +469,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
} }
public string CalculateDiscHashes() public string CalculateDiscHashes()
{ => DiscChecksumUtils.CalculateDiscHashesImpl(Discs);
var sb = new StringBuilder();
try
{
foreach (var disc in Discs)
{
sb.Append($"{new DiscHasher(disc).Calculate_PSX_RedumpHash():X8} {disc.Name}\r\n");
}
}
catch
{
// ignored
}
return sb.ToString();
}
public void ResetCounters() public void ResetCounters()
{ {