mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Win 8.1/10 support: Fixed crashes, added automatic download feature for the MSVC runtime
This commit is contained in:
parent
e4fa287e66
commit
a56aa15f28
18 changed files with 459 additions and 40 deletions
|
@ -179,7 +179,7 @@ void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFile
|
|||
}
|
||||
}
|
||||
|
||||
int AutoRomTest::Run(string filename)
|
||||
int32_t AutoRomTest::Run(string filename)
|
||||
{
|
||||
ZipReader zipReader;
|
||||
zipReader.LoadZipArchive(filename);
|
||||
|
|
|
@ -42,6 +42,6 @@ public:
|
|||
void Record(string filename, bool reset);
|
||||
void RecordFromMovie(string testFilename, string movieFilename);
|
||||
void RecordFromTest(string newTestFilename, string existingTestFilename);
|
||||
int Run(string filename);
|
||||
int32_t Run(string filename);
|
||||
void Stop();
|
||||
};
|
|
@ -169,7 +169,9 @@ void VideoDecoder::StopThread()
|
|||
|
||||
void VideoDecoder::RenderThread()
|
||||
{
|
||||
_renderer->Reset();
|
||||
if(_renderer) {
|
||||
_renderer->Reset();
|
||||
}
|
||||
while(!_stopFlag.load()) {
|
||||
//Wait until a frame is ready, or until 16ms have passed (to allow UI to run at a minimum of 60fps)
|
||||
_waitForRender.Wait(16);
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace Mesen.GUI.Config
|
|||
//Create new config file and save it to disk
|
||||
_config = new Configuration();
|
||||
_dirtyConfig = new Configuration();
|
||||
_config.InitializeDefaults();
|
||||
_dirtyConfig.InitializeDefaults();
|
||||
SaveConfig();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Mesen.GUI.Config
|
|||
PreferenceInfo = new PreferenceInfo();
|
||||
RecentFiles = new List<string>();
|
||||
Controllers = new List<ControllerInfo>();
|
||||
Cheats = new List<CheatInfo>();
|
||||
}
|
||||
|
||||
public void ApplyConfig()
|
||||
|
@ -47,7 +48,7 @@ namespace Mesen.GUI.Config
|
|||
InteropEmu.SetNesModel(Region);
|
||||
}
|
||||
|
||||
private void InitializeDefaults()
|
||||
public void InitializeDefaults()
|
||||
{
|
||||
while(Controllers.Count < 4) {
|
||||
var controllerInfo = new ControllerInfo();
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Mesen.GUI.Config
|
|||
public class KeyMappings
|
||||
{
|
||||
public string A = "A";
|
||||
public string B = "B";
|
||||
public string B = "S";
|
||||
public string Select = "W";
|
||||
public string Start = "Q";
|
||||
public string Up = "Up Arrow";
|
||||
|
|
100
GUI.NET/Forms/frmDownloadProgress.Designer.cs
generated
Normal file
100
GUI.NET/Forms/frmDownloadProgress.Designer.cs
generated
Normal file
|
@ -0,0 +1,100 @@
|
|||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
partial class frmDownloadProgress
|
||||
{
|
||||
/// <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.progressDownload = new System.Windows.Forms.ProgressBar();
|
||||
this.lblFilename = new System.Windows.Forms.Label();
|
||||
this.tmrStart = new System.Windows.Forms.Timer(this.components);
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// progressDownload
|
||||
//
|
||||
this.progressDownload.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.progressDownload.Location = new System.Drawing.Point(3, 38);
|
||||
this.progressDownload.Name = "progressDownload";
|
||||
this.progressDownload.Size = new System.Drawing.Size(328, 23);
|
||||
this.progressDownload.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
||||
this.progressDownload.TabIndex = 0;
|
||||
//
|
||||
// lblFilename
|
||||
//
|
||||
this.lblFilename.AutoSize = true;
|
||||
this.lblFilename.Location = new System.Drawing.Point(3, 5);
|
||||
this.lblFilename.Margin = new System.Windows.Forms.Padding(3, 5, 3, 0);
|
||||
this.lblFilename.Name = "lblFilename";
|
||||
this.lblFilename.Size = new System.Drawing.Size(100, 13);
|
||||
this.lblFilename.TabIndex = 1;
|
||||
this.lblFilename.Text = "Downloading file: ...";
|
||||
//
|
||||
// tmrStart
|
||||
//
|
||||
this.tmrStart.Tick += new System.EventHandler(this.tmrStart_Tick);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 1;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblFilename, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.progressDownload, 0, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(334, 67);
|
||||
this.tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// frmDownloadProgress
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(334, 67);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.MaximumSize = new System.Drawing.Size(350, 500);
|
||||
this.Name = "frmDownloadProgress";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Downloading...";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ProgressBar progressDownload;
|
||||
private System.Windows.Forms.Label lblFilename;
|
||||
private System.Windows.Forms.Timer tmrStart;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
}
|
||||
}
|
89
GUI.NET/Forms/frmDownloadProgress.cs
Normal file
89
GUI.NET/Forms/frmDownloadProgress.cs
Normal file
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
public partial class frmDownloadProgress : BaseForm
|
||||
{
|
||||
private string _link;
|
||||
private string _filename;
|
||||
private bool _cancel = false;
|
||||
|
||||
public frmDownloadProgress(string link, string filename)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_link = link;
|
||||
_filename = filename;
|
||||
|
||||
try {
|
||||
File.Delete(_filename);
|
||||
} catch {}
|
||||
|
||||
lblFilename.Text = link;
|
||||
|
||||
tmrStart.Start();
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
{
|
||||
_cancel = true;
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
private void tmrStart_Tick(object sender, EventArgs e)
|
||||
{
|
||||
tmrStart.Stop();
|
||||
|
||||
DialogResult result = System.Windows.Forms.DialogResult.None;
|
||||
|
||||
using(var client = new WebClient()) {
|
||||
client.DownloadProgressChanged += (object s, DownloadProgressChangedEventArgs args) => {
|
||||
progressDownload.Value = args.ProgressPercentage;
|
||||
};
|
||||
client.DownloadFileCompleted += (object s, AsyncCompletedEventArgs args) => {
|
||||
if(!args.Cancelled && args.Error == null && File.Exists(_filename)) {
|
||||
result = System.Windows.Forms.DialogResult.OK;
|
||||
} else if(args.Error != null) {
|
||||
MessageBox.Show("Unable to download file. Check your internet connection and try again." + Environment.NewLine + Environment.NewLine + "Details:" + Environment.NewLine + args.Error.Message, "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
result = System.Windows.Forms.DialogResult.Cancel;
|
||||
}
|
||||
};
|
||||
|
||||
Task downloadTask = null;
|
||||
try {
|
||||
downloadTask = client.DownloadFileTaskAsync(_link, _filename);
|
||||
} catch(Exception ex) {
|
||||
MessageBox.Show("Unable to download file. Check your internet connection and try again." + Environment.NewLine + Environment.NewLine + "Details:" + Environment.NewLine + ex.Message, "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
result = System.Windows.Forms.DialogResult.Cancel;
|
||||
}
|
||||
|
||||
if(downloadTask == null) {
|
||||
result = System.Windows.Forms.DialogResult.Cancel;
|
||||
} else {
|
||||
while(!downloadTask.IsCompleted && !_cancel) {
|
||||
System.Threading.Thread.Sleep(200);
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
if(_cancel) {
|
||||
client.CancelAsync();
|
||||
} else if(result == System.Windows.Forms.DialogResult.None) {
|
||||
result = System.Windows.Forms.DialogResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
DialogResult = result;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
126
GUI.NET/Forms/frmDownloadProgress.resx
Normal file
126
GUI.NET/Forms/frmDownloadProgress.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="tmrStart.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>107, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -276,6 +276,12 @@
|
|||
<Compile Include="Forms\Cheats\frmCheatList.Designer.cs">
|
||||
<DependentUpon>frmCheatList.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmDownloadProgress.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\frmDownloadProgress.Designer.cs">
|
||||
<DependentUpon>frmDownloadProgress.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\NetPlay\frmClientConfig.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -303,6 +309,7 @@
|
|||
<Compile Include="InteropEmu.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RuntimeChecker.cs" />
|
||||
<Compile Include="SingleInstance.cs" />
|
||||
<EmbeddedResource Include="Controls\ctrlTrackbar.resx">
|
||||
<DependentUpon>ctrlTrackbar.cs</DependentUpon>
|
||||
|
@ -391,6 +398,9 @@
|
|||
<EmbeddedResource Include="Forms\Cheats\frmCheatList.resx">
|
||||
<DependentUpon>frmCheatList.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\frmDownloadProgress.resx">
|
||||
<DependentUpon>frmDownloadProgress.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\frmMain.resx">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -6,12 +6,15 @@ using System.Linq;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI
|
||||
{
|
||||
public class InteropEmu
|
||||
{
|
||||
private const string DLLPath = "WinMesen.dll";
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool TestDll();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void InitializeEmu([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string homeFolder, IntPtr windowHandle, IntPtr dxViewerHandle);
|
||||
[DllImport(DLLPath)] public static extern void Release();
|
||||
|
||||
|
@ -28,16 +31,16 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern void Run();
|
||||
[DllImport(DLLPath)] public static extern void Pause();
|
||||
[DllImport(DLLPath)] public static extern void Resume();
|
||||
[DllImport(DLLPath)] public static extern bool IsPaused();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsPaused();
|
||||
[DllImport(DLLPath)] public static extern void Stop();
|
||||
[DllImport(DLLPath, EntryPoint="GetROMPath")] private static extern IntPtr GetROMPathWrapper();
|
||||
[DllImport(DLLPath)] public static extern void Reset();
|
||||
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port);
|
||||
[DllImport(DLLPath)] public static extern void StopServer();
|
||||
[DllImport(DLLPath)] public static extern bool IsServerRunning();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsServerRunning();
|
||||
[DllImport(DLLPath)] public static extern void Connect([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string host, UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string playerName, byte[] avatarData, UInt32 avatarSize);
|
||||
[DllImport(DLLPath)] public static extern void Disconnect();
|
||||
[DllImport(DLLPath)] public static extern bool IsConnected();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsConnected();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void TakeScreenshot();
|
||||
|
||||
|
@ -49,15 +52,15 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename);
|
||||
[DllImport(DLLPath)] public static extern void MovieRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool reset);
|
||||
[DllImport(DLLPath)] public static extern void MovieStop();
|
||||
[DllImport(DLLPath)] public static extern bool MoviePlaying();
|
||||
[DllImport(DLLPath)] public static extern bool MovieRecording();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MoviePlaying();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MovieRecording();
|
||||
|
||||
[DllImport(DLLPath)] public static extern Int32 RomTestRun([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename);
|
||||
[DllImport(DLLPath)] public static extern void RomTestRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool reset);
|
||||
[DllImport(DLLPath)] public static extern void RomTestRecordFromMovie([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string testFilename, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string movieFilename);
|
||||
[DllImport(DLLPath)] public static extern void RomTestRecordFromTest([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string newTestFilename, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string existingTestFilename);
|
||||
[DllImport(DLLPath)] public static extern void RomTestStop();
|
||||
[DllImport(DLLPath)] public static extern bool RomTestRecording();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool RomTestRecording();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void SaveState(UInt32 stateIndex);
|
||||
[DllImport(DLLPath)] public static extern void LoadState(UInt32 stateIndex);
|
||||
|
@ -91,7 +94,7 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern void DebugStepOut();
|
||||
[DllImport(DLLPath)] public static extern void DebugStepOver();
|
||||
[DllImport(DLLPath)] public static extern void DebugRun();
|
||||
[DllImport(DLLPath)] public static extern bool DebugIsCodeChanged();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool DebugIsCodeChanged();
|
||||
[DllImport(DLLPath)] public static extern IntPtr DebugGetCode();
|
||||
[DllImport(DLLPath)] public static extern Byte DebugGetMemoryValue(UInt32 addr);
|
||||
[DllImport(DLLPath)] public static extern UInt32 DebugGetRelativeAddress(UInt32 addr);
|
||||
|
|
|
@ -21,6 +21,10 @@ namespace Mesen.GUI
|
|||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if(!RuntimeChecker.TestDll()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Guid guid = new Guid("{A46606B7-2D1C-4CC5-A52F-43BCAF094AED}");
|
||||
using(SingleInstance singleInstance = new SingleInstance(guid)) {
|
||||
if(singleInstance.FirstInstance || !Config.ConfigManager.Config.PreferenceInfo.SingleInstance) {
|
||||
|
|
74
GUI.NET/RuntimeChecker.cs
Normal file
74
GUI.NET/RuntimeChecker.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Forms;
|
||||
|
||||
namespace Mesen.GUI
|
||||
{
|
||||
class RuntimeChecker
|
||||
{
|
||||
public static bool TestDll()
|
||||
{
|
||||
try {
|
||||
return InteropEmu.TestDll();
|
||||
} catch { }
|
||||
|
||||
if(!File.Exists("WinMesen.dll")) {
|
||||
MessageBox.Show("Mesen was unable to start due to missing files." + Environment.NewLine + Environment.NewLine + "Error: WinMesen.dll is missing.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
} else {
|
||||
if(MessageBox.Show("Mesen was unable to start due to missing dependencies." + Environment.NewLine + Environment.NewLine + "Mesen requires the the Visual Studio 2013 runtime. Would you like to download the runtime from Microsoft's website and install it?", "Mesen", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
|
||||
if(!RuntimeChecker.DownloadRuntime()) {
|
||||
MessageBox.Show("The Visual Studio Runtime could not be installed properly.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
} else {
|
||||
Process.Start(Process.GetCurrentProcess().MainModule.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool DownloadRuntime()
|
||||
{
|
||||
string link = string.Empty;
|
||||
if(IntPtr.Size == 4) {
|
||||
//x86
|
||||
link = "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe";
|
||||
} else {
|
||||
//x64
|
||||
link = "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe";
|
||||
}
|
||||
|
||||
string tempFilename = Path.GetTempPath() + "Mesen_VsRuntime2013.exe";
|
||||
|
||||
try {
|
||||
frmDownloadProgress frm = new frmDownloadProgress(link, tempFilename);
|
||||
|
||||
if(frm.ShowDialog() == DialogResult.OK) {
|
||||
Process installer = Process.Start(tempFilename, "/passive /norestart");
|
||||
installer.WaitForExit();
|
||||
if(installer.ExitCode != 0) {
|
||||
MessageBox.Show("Unexpected error: " + installer.ExitCode, "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
} else {
|
||||
//Runtime should now be installed, try to launch Mesen again
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
MessageBox.Show("Unexpected error: " + Environment.NewLine + e.Message, "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
} finally {
|
||||
try {
|
||||
File.Delete(tempFilename);
|
||||
} catch { }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,6 +42,11 @@ namespace InteropEmu {
|
|||
};
|
||||
|
||||
extern "C" {
|
||||
DllExport bool __stdcall TestDll()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DllExport void __stdcall InitializeEmu(const char* homeFolder, HWND windowHandle, HWND dxViewerHandle)
|
||||
{
|
||||
FolderUtilities::SetHomeFolder(homeFolder);
|
||||
|
@ -84,7 +89,7 @@ namespace InteropEmu {
|
|||
}
|
||||
|
||||
DllExport void __stdcall Resume() { EmulationSettings::ClearFlags(EmulationFlags::Paused); }
|
||||
DllExport int __stdcall IsPaused() { return EmulationSettings::CheckFlag(EmulationFlags::Paused); }
|
||||
DllExport bool __stdcall IsPaused() { return EmulationSettings::CheckFlag(EmulationFlags::Paused); }
|
||||
DllExport void __stdcall Stop()
|
||||
{
|
||||
if(Console::GetInstance()) {
|
||||
|
@ -101,7 +106,7 @@ namespace InteropEmu {
|
|||
|
||||
DllExport void __stdcall StartServer(uint16_t port) { GameServer::StartServer(port); }
|
||||
DllExport void __stdcall StopServer() { GameServer::StopServer(); }
|
||||
DllExport int __stdcall IsServerRunning() { return GameServer::Started(); }
|
||||
DllExport bool __stdcall IsServerRunning() { return GameServer::Started(); }
|
||||
|
||||
DllExport void __stdcall Connect(char* host, uint16_t port, char* playerName, uint8_t* avatarData, uint32_t avatarSize)
|
||||
{
|
||||
|
@ -117,7 +122,7 @@ namespace InteropEmu {
|
|||
}
|
||||
|
||||
DllExport void __stdcall Disconnect() { GameClient::Disconnect(); }
|
||||
DllExport int __stdcall IsConnected() { return GameClient::Connected(); }
|
||||
DllExport bool __stdcall IsConnected() { return GameClient::Connected(); }
|
||||
|
||||
DllExport void __stdcall Pause()
|
||||
{
|
||||
|
@ -155,10 +160,10 @@ namespace InteropEmu {
|
|||
DllExport void __stdcall MoviePlay(char* filename) { Movie::Play(filename); }
|
||||
DllExport void __stdcall MovieRecord(char* filename, bool reset) { Movie::Record(filename, reset); }
|
||||
DllExport void __stdcall MovieStop() { Movie::Stop(); }
|
||||
DllExport int __stdcall MoviePlaying() { return Movie::Playing(); }
|
||||
DllExport int __stdcall MovieRecording() { return Movie::Recording(); }
|
||||
DllExport bool __stdcall MoviePlaying() { return Movie::Playing(); }
|
||||
DllExport bool __stdcall MovieRecording() { return Movie::Recording(); }
|
||||
|
||||
DllExport int __stdcall RomTestRun(char* filename)
|
||||
DllExport int32_t __stdcall RomTestRun(char* filename)
|
||||
{
|
||||
AutoRomTest romTest;
|
||||
return romTest.Run(filename);
|
||||
|
@ -194,7 +199,7 @@ namespace InteropEmu {
|
|||
}
|
||||
}
|
||||
|
||||
DllExport int __stdcall RomTestRecording() { return _autoRomTest != nullptr; }
|
||||
DllExport bool __stdcall RomTestRecording() { return _autoRomTest != nullptr; }
|
||||
|
||||
DllExport void __stdcall CheatAddCustom(uint32_t address, uint8_t value, int32_t compareValue, bool isRelativeAddress) { CheatManager::AddCustomCode(address, value, compareValue, isRelativeAddress); }
|
||||
DllExport void __stdcall CheatAddGameGenie(char* code) { CheatManager::AddGameGenieCode(code); }
|
||||
|
|
|
@ -35,7 +35,7 @@ extern "C"
|
|||
DllExport void __stdcall DebugStepCycles(uint32_t count) { GetDebugger()->StepCycles(count); }
|
||||
DllExport void __stdcall DebugStepOver() { GetDebugger()->StepOver(); }
|
||||
DllExport void __stdcall DebugStepOut() { GetDebugger()->StepOut(); }
|
||||
DllExport uint32_t __stdcall DebugIsCodeChanged() { return GetDebugger()->IsCodeChanged(); }
|
||||
DllExport bool __stdcall DebugIsCodeChanged() { return GetDebugger()->IsCodeChanged(); }
|
||||
DllExport const char* __stdcall DebugGetCode() { return GetDebugger()->GetCode()->c_str(); }
|
||||
|
||||
DllExport void __stdcall DebugSetNextStatement(uint16_t addr) { GetDebugger()->SetNextStatement(addr); }
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace NES
|
|||
|
||||
SetScreenSize(256, 240);
|
||||
|
||||
VideoDecoder::GetInstance()->RegisterRenderingDevice(this);
|
||||
MessageManager::RegisterMessageManager(this);
|
||||
}
|
||||
|
||||
|
@ -55,6 +54,8 @@ namespace NES
|
|||
CleanupDevice();
|
||||
if(FAILED(InitDevice())) {
|
||||
CleanupDevice();
|
||||
} else {
|
||||
VideoDecoder::GetInstance()->RegisterRenderingDevice(this);
|
||||
}
|
||||
_frameLock.Release();
|
||||
}
|
||||
|
@ -117,15 +118,17 @@ namespace NES
|
|||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
|
||||
D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_NULL;
|
||||
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1;
|
||||
for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) {
|
||||
_driverType = driverTypes[driverTypeIndex];
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pDeviceContext);
|
||||
driverType = driverTypes[driverTypeIndex];
|
||||
featureLevel = D3D_FEATURE_LEVEL_11_1;
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &featureLevel, &_pDeviceContext);
|
||||
|
||||
if(hr == E_INVALIDARG) {
|
||||
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pDeviceContext);
|
||||
featureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &featureLevel, &_pDeviceContext);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr)) {
|
||||
|
@ -168,7 +171,7 @@ namespace NES
|
|||
|
||||
// Create the state using the device.
|
||||
if(FAILED(_pd3dDevice->CreateDepthStencilState(&depthDisabledStencilDesc, &_pDepthDisabledStencilState))) {
|
||||
return false;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Clear the blend state description.
|
||||
|
@ -187,7 +190,7 @@ namespace NES
|
|||
|
||||
// Create the blend state using the description.
|
||||
if(FAILED(_pd3dDevice->CreateBlendState(&blendStateDescription, &_pAlphaEnableBlendingState))) {
|
||||
return false;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
float blendFactor[4];
|
||||
|
@ -212,12 +215,12 @@ namespace NES
|
|||
|
||||
_pTexture = CreateTexture(_nesFrameWidth, _nesFrameHeight);
|
||||
if(!_pTexture) {
|
||||
return 0;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
_overlayTexture = CreateTexture(8, 8);
|
||||
if(!_overlayTexture) {
|
||||
return 0;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -243,7 +246,7 @@ namespace NES
|
|||
_pd3dDevice->CreateSamplerState(&samplerDesc, &_samplerState);
|
||||
|
||||
if(!FAILED(CreateDDSTextureFromFile(_pd3dDevice, L"Resources\\Toast.dds", nullptr, &_toastTexture))) {
|
||||
return 0;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -253,9 +256,6 @@ namespace NES
|
|||
{
|
||||
ID3D11Texture2D* texture;
|
||||
|
||||
UINT fred;
|
||||
_pd3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM, 16, &fred);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
|
||||
desc.ArraySize = 1;
|
||||
|
@ -265,13 +265,14 @@ namespace NES
|
|||
desc.MipLevels = 1;
|
||||
desc.MiscFlags = 0;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = fred;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
if(FAILED(_pd3dDevice->CreateTexture2D(&desc, nullptr, &texture))) {
|
||||
HRESULT hr = _pd3dDevice->CreateTexture2D(&desc, nullptr, &texture);
|
||||
if(FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return texture;
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace NES {
|
|||
private:
|
||||
HWND _hWnd = nullptr;
|
||||
|
||||
D3D_DRIVER_TYPE _driverType = D3D_DRIVER_TYPE_NULL;
|
||||
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
ID3D11Device* _pd3dDevice = nullptr;
|
||||
ID3D11DeviceContext* _pDeviceContext = nullptr;
|
||||
IDXGISwapChain* _pSwapChain = nullptr;
|
||||
|
|
|
@ -5,12 +5,16 @@
|
|||
|
||||
SoundManager::SoundManager(HWND hwnd)
|
||||
{
|
||||
SoundMixer::RegisterAudioDevice(this);
|
||||
|
||||
_hWnd = hwnd;
|
||||
_directSound = 0;
|
||||
_primaryBuffer = 0;
|
||||
_secondaryBuffer = 0;
|
||||
|
||||
if(InitializeDirectSound(44100)) {
|
||||
SoundMixer::RegisterAudioDevice(this);
|
||||
} else {
|
||||
MessageManager::DisplayMessage("Error", "Could not initialize audio system");
|
||||
}
|
||||
}
|
||||
|
||||
SoundManager::~SoundManager()
|
||||
|
|
Loading…
Add table
Reference in a new issue