UI: Added support for zip/7z files
This commit is contained in:
parent
82834a1753
commit
f4ad787721
9 changed files with 569 additions and 2 deletions
|
@ -95,7 +95,7 @@ extern "C" {
|
|||
std::ostringstream out;
|
||||
shared_ptr<ArchiveReader> reader = ArchiveReader::GetReader(filename);
|
||||
if(reader) {
|
||||
for(string romName : reader->GetFileList({ ".sfc" })) {
|
||||
for(string romName : reader->GetFileList(VirtualFile::RomExtensions)) {
|
||||
out << romName << "[!|!]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ namespace Mesen.GUI
|
|||
|
||||
public static void LoadRom(ResourcePath romPath, ResourcePath? patchPath = null)
|
||||
{
|
||||
if(!frmSelectRom.SelectRom(ref romPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EmuApi.LoadRom(romPath, patchPath);
|
||||
|
||||
ConfigManager.Config.RecentFiles.AddRecentFile(romPath, patchPath);
|
||||
|
|
137
UI/Forms/frmSelectRom.cs
Normal file
137
UI/Forms/frmSelectRom.cs
Normal file
|
@ -0,0 +1,137 @@
|
|||
using Mesen.GUI.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
public partial class frmSelectRom : BaseForm
|
||||
{
|
||||
private List<ArchiveRomEntry> _romFiles;
|
||||
private int SelectedIndex { get; set; }
|
||||
private string _previousSearch = "";
|
||||
|
||||
private frmSelectRom(List<ArchiveRomEntry> romFiles)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_romFiles = romFiles;
|
||||
lblRomCount.Text = ResourceHelper.GetMessage("RomsFound", _romFiles.Count.ToString());
|
||||
|
||||
lstRoms.Sorted = true;
|
||||
this.DialogResult = DialogResult.Cancel;
|
||||
|
||||
UpdateList();
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if(txtSearch.Focused) {
|
||||
if(keyData == Keys.Down || keyData == Keys.PageDown || keyData == Keys.Up || keyData == Keys.PageUp) {
|
||||
lstRoms.Focus();
|
||||
if(lstRoms.Items.Count > 0) {
|
||||
lstRoms.SelectedIndex = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if(lstRoms.Focused && lstRoms.SelectedIndex <= 0) {
|
||||
if(keyData == Keys.Up || keyData == Keys.PageUp) {
|
||||
txtSearch.Focus();
|
||||
txtSearch.SelectAll();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(keyData == Keys.Enter && lstRoms.Focused && lstRoms.SelectedItems.Count == 1) {
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
private void UpdateList()
|
||||
{
|
||||
lstRoms.Items.Clear();
|
||||
if(string.IsNullOrWhiteSpace(_previousSearch)) {
|
||||
lstRoms.Items.AddRange(_romFiles.ToArray());
|
||||
} else {
|
||||
List<ArchiveRomEntry> romsToAdd = new List<ArchiveRomEntry>();
|
||||
foreach(ArchiveRomEntry rom in _romFiles) {
|
||||
if(rom.Filename.IndexOf(_previousSearch, StringComparison.InvariantCultureIgnoreCase) >= 0) {
|
||||
romsToAdd.Add(rom);
|
||||
}
|
||||
}
|
||||
lstRoms.Items.AddRange(romsToAdd.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
txtSearch.Focus();
|
||||
}
|
||||
|
||||
public static bool SelectRom(ref ResourcePath resource)
|
||||
{
|
||||
List<ArchiveRomEntry> archiveRomList = ArchiveHelper.GetArchiveRomList(resource.Path);
|
||||
|
||||
if(archiveRomList.Select(entry => entry.Filename).Contains(resource.InnerFile)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(archiveRomList.Count > 1) {
|
||||
using(frmSelectRom frm = new frmSelectRom(archiveRomList)) {
|
||||
if(frm.ShowDialog(null, Application.OpenForms[0]) == DialogResult.OK) {
|
||||
ArchiveRomEntry entry = frm.lstRoms.SelectedItem as ArchiveRomEntry;
|
||||
resource.InnerFile = entry.Filename;
|
||||
if(!entry.IsUtf8) {
|
||||
resource.InnerFileIndex = archiveRomList.IndexOf(entry) + 1;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if(archiveRomList.Count == 1) {
|
||||
resource.InnerFile = archiveRomList[0].Filename;
|
||||
if(!archiveRomList[0].IsUtf8) {
|
||||
resource.InnerFileIndex = 1;
|
||||
}
|
||||
} else {
|
||||
resource.InnerFile = "";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void lstRoms_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
btnOK.Enabled = lstRoms.SelectedItems.Count > 0;
|
||||
}
|
||||
|
||||
private void tmrSearch_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if(txtSearch.Text.Trim() != _previousSearch) {
|
||||
_previousSearch = txtSearch.Text.Trim();
|
||||
UpdateList();
|
||||
}
|
||||
}
|
||||
|
||||
private void lstRoms_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstRoms.SelectedItems.Count == 1) {
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
196
UI/Forms/frmSelectRom.designer.cs
generated
Normal file
196
UI/Forms/frmSelectRom.designer.cs
generated
Normal file
|
@ -0,0 +1,196 @@
|
|||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
partial class frmSelectRom
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lstRoms = new System.Windows.Forms.ListBox();
|
||||
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.btnOK = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.lblRomCount = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.txtSearch = new System.Windows.Forms.TextBox();
|
||||
this.lblSearch = new System.Windows.Forms.Label();
|
||||
this.tmrSearch = new System.Windows.Forms.Timer(this.components);
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.flowLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.lstRoms, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblRomCount, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(463, 242);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// lstRoms
|
||||
//
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.lstRoms, 2);
|
||||
this.lstRoms.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstRoms.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lstRoms.FormattingEnabled = true;
|
||||
this.lstRoms.ItemHeight = 16;
|
||||
this.lstRoms.Location = new System.Drawing.Point(3, 28);
|
||||
this.lstRoms.Name = "lstRoms";
|
||||
this.lstRoms.Size = new System.Drawing.Size(457, 182);
|
||||
this.lstRoms.TabIndex = 1;
|
||||
this.lstRoms.SelectedIndexChanged += new System.EventHandler(this.lstRoms_SelectedIndexChanged);
|
||||
this.lstRoms.DoubleClick += new System.EventHandler(this.lstRoms_DoubleClick);
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowLayoutPanel1.AutoSize = true;
|
||||
this.flowLayoutPanel1.Controls.Add(this.btnOK);
|
||||
this.flowLayoutPanel1.Controls.Add(this.btnCancel);
|
||||
this.flowLayoutPanel1.Location = new System.Drawing.Point(301, 213);
|
||||
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
this.flowLayoutPanel1.Size = new System.Drawing.Size(162, 29);
|
||||
this.flowLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btnOK.Enabled = false;
|
||||
this.btnOK.Location = new System.Drawing.Point(3, 3);
|
||||
this.btnOK.Name = "btnOK";
|
||||
this.btnOK.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnOK.TabIndex = 0;
|
||||
this.btnOK.Text = "OK";
|
||||
this.btnOK.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(84, 3);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnCancel.TabIndex = 1;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblRomCount
|
||||
//
|
||||
this.lblRomCount.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblRomCount.AutoSize = true;
|
||||
this.lblRomCount.Location = new System.Drawing.Point(3, 221);
|
||||
this.lblRomCount.Name = "lblRomCount";
|
||||
this.lblRomCount.Size = new System.Drawing.Size(83, 13);
|
||||
this.lblRomCount.TabIndex = 2;
|
||||
this.lblRomCount.Text = "### roms found";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel2, 2);
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.txtSearch, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblSearch, 0, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 1;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(463, 25);
|
||||
this.tableLayoutPanel2.TabIndex = 5;
|
||||
//
|
||||
// txtSearch
|
||||
//
|
||||
this.txtSearch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtSearch.Location = new System.Drawing.Point(53, 3);
|
||||
this.txtSearch.Name = "txtSearch";
|
||||
this.txtSearch.Size = new System.Drawing.Size(407, 20);
|
||||
this.txtSearch.TabIndex = 1;
|
||||
//
|
||||
// lblSearch
|
||||
//
|
||||
this.lblSearch.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblSearch.AutoSize = true;
|
||||
this.lblSearch.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblSearch.Name = "lblSearch";
|
||||
this.lblSearch.Size = new System.Drawing.Size(44, 13);
|
||||
this.lblSearch.TabIndex = 3;
|
||||
this.lblSearch.Text = "Search:";
|
||||
//
|
||||
// tmrSearch
|
||||
//
|
||||
this.tmrSearch.Enabled = true;
|
||||
this.tmrSearch.Tick += new System.EventHandler(this.tmrSearch_Tick);
|
||||
//
|
||||
// frmSelectRom
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(463, 242);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Name = "frmSelectRom";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Select Rom...";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.flowLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.ListBox lstRoms;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.Button btnOK;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Label lblRomCount;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.TextBox txtSearch;
|
||||
private System.Windows.Forms.Label lblSearch;
|
||||
private System.Windows.Forms.Timer tmrSearch;
|
||||
}
|
||||
}
|
126
UI/Forms/frmSelectRom.resx
Normal file
126
UI/Forms/frmSelectRom.resx
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="tmrSearch.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>107, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -44,6 +44,8 @@ namespace Mesen.GUI
|
|||
|
||||
[DllImport(DllPath, EntryPoint = "GetLog")] private static extern IntPtr GetLogWrapper();
|
||||
public static string GetLog() { return Utf8Marshaler.PtrToStringUtf8(EmuApi.GetLogWrapper()).Replace("\n", Environment.NewLine); }
|
||||
|
||||
[DllImport(DllPath)] public static extern IntPtr GetArchiveRomList([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filename);
|
||||
}
|
||||
|
||||
public struct ScreenSize
|
||||
|
|
10
UI/UI.csproj
10
UI/UI.csproj
|
@ -491,6 +491,12 @@
|
|||
<Compile Include="Forms\frmMain.Designer.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmSelectRom.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmSelectRom.designer.cs">
|
||||
<DependentUpon>frmSelectRom.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\MesenMsgBox.cs" />
|
||||
<Compile Include="Forms\OpenSaveFileDialogExtensions.cs" />
|
||||
<Compile Include="Forms\ResourceHelper.cs" />
|
||||
|
@ -506,6 +512,7 @@
|
|||
<Compile Include="EmuRunner.cs" />
|
||||
<Compile Include="RuntimeChecker.cs" />
|
||||
<Compile Include="SingleInstance.cs" />
|
||||
<Compile Include="Utilities\ArchiveHelper.cs" />
|
||||
<Compile Include="Utilities\HexConverter.cs" />
|
||||
<Compile Include="Utilities\Md5Helper.cs" />
|
||||
<Compile Include="Utilities\XmlColor.cs" />
|
||||
|
@ -615,6 +622,9 @@
|
|||
<EmbeddedResource Include="Forms\frmMain.resx">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\frmSelectRom.resx">
|
||||
<DependentUpon>frmSelectRom.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
|
|
92
UI/Utilities/ArchiveHelper.cs
Normal file
92
UI/Utilities/ArchiveHelper.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Utilities
|
||||
{
|
||||
class ArchiveHelper
|
||||
{
|
||||
public static List<ArchiveRomEntry> GetArchiveRomList(string archivePath)
|
||||
{
|
||||
//Split the array on the [!|!] delimiter
|
||||
byte[] buffer = PtrToByteArray(EmuApi.GetArchiveRomList(archivePath));
|
||||
List<List<byte>> filenames = new List<List<byte>>();
|
||||
List<byte> filenameBytes = new List<byte>();
|
||||
for(int i = 0; i < buffer.Length - 5; i++) {
|
||||
if(buffer[i] == '[' && buffer[i + 1] == '!' && buffer[i + 2] == '|' && buffer[i + 3] == '!' && buffer[i + 4] == ']') {
|
||||
if(filenameBytes.Count > 0) {
|
||||
filenames.Add(filenameBytes);
|
||||
}
|
||||
filenameBytes = new List<byte>();
|
||||
i += 4;
|
||||
} else {
|
||||
filenameBytes.Add(buffer[i]);
|
||||
}
|
||||
}
|
||||
if(filenameBytes.Count > 0) {
|
||||
filenames.Add(filenameBytes);
|
||||
}
|
||||
|
||||
List<ArchiveRomEntry> entries = new List<ArchiveRomEntry>();
|
||||
|
||||
//Check whether or not each string is a valid utf8 filename, if not decode it using the system's default encoding.
|
||||
//This is necessary because zip files do not have any rules when it comes to encoding filenames
|
||||
for(int i = 0; i < filenames.Count; i++) {
|
||||
byte[] originalBytes = filenames[i].ToArray();
|
||||
string utf8Filename = Encoding.UTF8.GetString(originalBytes);
|
||||
byte[] convertedBytes = Encoding.UTF8.GetBytes(utf8Filename);
|
||||
bool equal = true;
|
||||
if(originalBytes.Length == convertedBytes.Length) {
|
||||
for(int j = 0; j < convertedBytes.Length; j++) {
|
||||
if(convertedBytes[j] != originalBytes[j]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
equal = false;
|
||||
}
|
||||
|
||||
if(!equal) {
|
||||
//String doesn't appear to be an utf8 string, use the system's default encoding
|
||||
entries.Add(new ArchiveRomEntry() { Filename = Encoding.Default.GetString(originalBytes), IsUtf8 = false });
|
||||
} else {
|
||||
entries.Add(new ArchiveRomEntry() { Filename = utf8Filename, IsUtf8 = true });
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static byte[] PtrToByteArray(IntPtr ptr)
|
||||
{
|
||||
if(ptr == IntPtr.Zero) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
int len = 0;
|
||||
while(Marshal.ReadByte(ptr, len) != 0) {
|
||||
len++;
|
||||
}
|
||||
|
||||
byte[] array = new byte[len];
|
||||
Marshal.Copy(ptr, array, 0, len);
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public class ArchiveRomEntry
|
||||
{
|
||||
public string Filename;
|
||||
public bool IsUtf8;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Filename;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
#include "../Utilities/UpsPatcher.h"
|
||||
|
||||
//TODO
|
||||
const std::initializer_list<string> VirtualFile::RomExtensions = { ".nes", ".fds", ".nsf", ".nsfe", "*.unf", "*.unif" };
|
||||
const std::initializer_list<string> VirtualFile::RomExtensions = { ".sfc", ".smc", ".swc", ".fig" };
|
||||
|
||||
VirtualFile::VirtualFile()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue