complete speed/skip/non60-throttle functionality and controllable vsync. maybe a bit rough, but i'll continue to support it.

This commit is contained in:
zeromus 2011-02-21 09:48:53 +00:00
parent 1d2d5ff39e
commit bc74d6c575
21 changed files with 2616 additions and 416 deletions

View File

@ -441,6 +441,12 @@ namespace BizHawk.Emulation.Consoles.Calculator
public string SystemId { get { return "TI83"; } }
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } }
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -846,5 +846,11 @@ namespace BizHawk.Emulation.Consoles.Gameboy
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } }
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -159,5 +159,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public string SystemId { get { return "NES"; } }
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } }
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -281,5 +281,16 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
private IList<MemoryDomain> memoryDomains;
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
public object Query(EmulatorQuery query)
{
switch (query)
{
case EmulatorQuery.VsyncRate:
return 60.0;
default:
return null;
}
}
}
}

View File

@ -187,5 +187,11 @@ namespace BizHawk.Emulation.Consoles.Sega
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } }
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -354,5 +354,11 @@ namespace BizHawk.Emulation.Consoles.Sega
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -46,6 +46,9 @@ namespace BizHawk
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
public object Query(EmulatorQuery query)
{
return null;
}
}
}

View File

@ -31,6 +31,9 @@ namespace BizHawk
void LoadStateBinary(BinaryReader reader);
byte[] SaveStateBinary();
//arbitrary extensible query mechanism
object Query(EmulatorQuery query);
// ----- Client Debugging API stuff -----
IList<MemoryDomain> MemoryDomains { get; }
MemoryDomain MainMemory { get; }
@ -63,4 +66,9 @@ namespace BizHawk
public enum Endian { Big, Little, Unknown }
public enum DisplayType { NTSC, PAL }
public enum EmulatorQuery
{
VsyncRate
}
}

View File

@ -32,11 +32,16 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox));
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.HR = new BizHawk.Core.HorizontalLine();
this.label5 = new System.Windows.Forms.Label();
this.mom1 = new System.Windows.Forms.PictureBox();
this.mom2 = new System.Windows.Forms.PictureBox();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.mom1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.mom2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
@ -44,7 +49,7 @@
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 72F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(0, 9);
this.label1.Location = new System.Drawing.Point(0, -3);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(490, 108);
this.label1.TabIndex = 1;
@ -60,16 +65,6 @@
this.label2.TabIndex = 2;
this.label2.Text = "EMULATES\r\nYOUR\r\nMOM";
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(155, 108);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(171, 216);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// timer1
//
this.timer1.Enabled = true;
@ -105,11 +100,53 @@
this.HR.TabIndex = 4;
this.HR.Text = "COPYRITE 2001";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label5.Location = new System.Drawing.Point(222, 369);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(104, 55);
this.label5.TabIndex = 8;
this.label5.Text = "--->";
//
// mom1
//
this.mom1.Image = ((System.Drawing.Image)(resources.GetObject("mom1.Image")));
this.mom1.Location = new System.Drawing.Point(372, 274);
this.mom1.Name = "mom1";
this.mom1.Size = new System.Drawing.Size(115, 150);
this.mom1.TabIndex = 7;
this.mom1.TabStop = false;
this.mom1.Visible = false;
//
// mom2
//
this.mom2.Image = ((System.Drawing.Image)(resources.GetObject("mom2.Image")));
this.mom2.Location = new System.Drawing.Point(372, 274);
this.mom2.Name = "mom2";
this.mom2.Size = new System.Drawing.Size(115, 150);
this.mom2.TabIndex = 6;
this.mom2.TabStop = false;
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(155, 108);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(171, 216);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// AboutBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(519, 497);
this.Controls.Add(this.label5);
this.Controls.Add(this.mom1);
this.Controls.Add(this.mom2);
this.Controls.Add(this.label4);
this.Controls.Add(this.HR);
this.Controls.Add(this.label3);
@ -118,6 +155,8 @@
this.Controls.Add(this.pictureBox1);
this.Name = "AboutBox";
this.Text = "AboutBox";
((System.ComponentModel.ISupportInitialize)(this.mom1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.mom2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@ -133,5 +172,8 @@
private System.Windows.Forms.Label label3;
private BizHawk.Core.HorizontalLine HR;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.PictureBox mom2;
private System.Windows.Forms.PictureBox mom1;
private System.Windows.Forms.Label label5;
}
}

View File

@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Text;
using System.Windows.Forms;
@ -11,17 +12,72 @@ namespace BizHawk.MultiClient
{
public partial class AboutBox : Form
{
SoundPlayer sfx;
Random r = new Random();
int ctr = 0;
Point loc;
public AboutBox()
{
InitializeComponent();
label1.ForeColor = Color.LightGreen;
loc = label1.Location;
label1.Text = "";
try
{
var rm = new System.Resources.ResourceManager("BizHawk.MultiClient.Properties.Resources", GetType().Assembly);
sfx = new SoundPlayer(rm.GetStream("nothawk"));
sfx.Play();
}
catch
{
}
}
protected override void OnClosed(EventArgs e)
{
if(sfx != null)
sfx.Dispose();
}
int smack = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (label1.ForeColor == Color.LightGreen)
label1.ForeColor = Color.Pink;
else label1.ForeColor = Color.LightGreen;
ctr++;
if (ctr == 3)
label1.Text = "BIZ";
else if (ctr == 10)
label1.Text = "BIZ HAWK";
else if (ctr == 20)
{
label1.ForeColor = Color.LightGreen;
label1.Text = "BIZHAWK";
}
else if (ctr > 20)
{
if (label1.ForeColor == Color.LightGreen)
label1.ForeColor = Color.Pink;
else label1.ForeColor = Color.LightGreen;
}
if (ctr/5 % 2 ==0)
{
mom1.Visible = true;
mom2.Visible = false;
}
else
{
mom1.Visible = false;
mom2.Visible = true;
}
if (ctr > 30)
{
if(ctr/7%7<4)
label1.Location = new Point(loc.X + r.Next(3) - 1, loc.Y + r.Next(3) - 1);
else
label1.Location = new Point(loc.X + r.Next(5) - 3, loc.Y + r.Next(5) - 3);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{DD448B37-BA3F-4544-9754-5406E8094723}</ProjectGuid>
<OutputType>Exe</OutputType>
@ -107,6 +107,10 @@
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.MenuItems.cs">
<DependentUpon>MainForm.cs</DependentUpon>
<SubType>Form</SubType>
</Compile>
<Compile Include="MruStack.cs" />
<Compile Include="NameStateForm.cs">
<SubType>Form</SubType>

View File

@ -28,6 +28,14 @@
public int MainWndx = -1; //Negative numbers will be ignored
public int MainWndy = -1;
// Run-Control settings
public int FrameProgressDelayMs = 500; //how long until a frame advance hold turns into a frame progress?
public int FrameSkip = 0;
public int SpeedPercent = 100;
public bool LimitFramerate = true;
public bool AutoMinimizeSkipping = true;
public bool DisplayVSync = false;
// Display options
public bool DisplayFPS = false;
public bool DisplayFrameCounter = false;

View File

@ -123,6 +123,27 @@
this.pauseWhenMenuActivatedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveWindowPositionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.startPausedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.frameSkipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.miLimitFramerate = new System.Windows.Forms.ToolStripMenuItem();
this.miDisplayVsync = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.miAutoMinimizeSkipping = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip0 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip1 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip2 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip3 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip4 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip5 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip6 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip7 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip8 = new System.Windows.Forms.ToolStripMenuItem();
this.miFrameskip9 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.miSpeed50 = new System.Windows.Forms.ToolStripMenuItem();
this.miSpeed75 = new System.Windows.Forms.ToolStripMenuItem();
this.miSpeed100 = new System.Windows.Forms.ToolStripMenuItem();
this.miSpeed150 = new System.Windows.Forms.ToolStripMenuItem();
this.miSpeed200 = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.rAMWatchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.rAMSearchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -834,7 +855,8 @@
this.hotkeysToolStripMenuItem,
this.toolStripSeparator9,
this.soundToolStripMenuItem,
this.gUIToolStripMenuItem});
this.gUIToolStripMenuItem,
this.frameSkipToolStripMenuItem});
this.configToolStripMenuItem.Name = "configToolStripMenuItem";
this.configToolStripMenuItem.Size = new System.Drawing.Size(50, 20);
this.configToolStripMenuItem.Text = "&Config";
@ -842,26 +864,26 @@
// controllersToolStripMenuItem
//
this.controllersToolStripMenuItem.Name = "controllersToolStripMenuItem";
this.controllersToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.controllersToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.controllersToolStripMenuItem.Text = "&Controllers";
this.controllersToolStripMenuItem.Click += new System.EventHandler(this.controllersToolStripMenuItem_Click);
//
// hotkeysToolStripMenuItem
//
this.hotkeysToolStripMenuItem.Name = "hotkeysToolStripMenuItem";
this.hotkeysToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.hotkeysToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.hotkeysToolStripMenuItem.Text = "&Hotkeys";
this.hotkeysToolStripMenuItem.Click += new System.EventHandler(this.hotkeysToolStripMenuItem_Click);
//
// toolStripSeparator9
//
this.toolStripSeparator9.Name = "toolStripSeparator9";
this.toolStripSeparator9.Size = new System.Drawing.Size(134, 6);
this.toolStripSeparator9.Size = new System.Drawing.Size(149, 6);
//
// soundToolStripMenuItem
//
this.soundToolStripMenuItem.Name = "soundToolStripMenuItem";
this.soundToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.soundToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.soundToolStripMenuItem.Text = "&Sound";
this.soundToolStripMenuItem.Click += new System.EventHandler(this.soundToolStripMenuItem_Click);
//
@ -872,7 +894,7 @@
this.saveWindowPositionToolStripMenuItem,
this.startPausedToolStripMenuItem});
this.gUIToolStripMenuItem.Name = "gUIToolStripMenuItem";
this.gUIToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.gUIToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.gUIToolStripMenuItem.Text = "GUI";
this.gUIToolStripMenuItem.DropDownOpened += new System.EventHandler(this.gUIToolStripMenuItem_DropDownOpened);
//
@ -897,6 +919,170 @@
this.startPausedToolStripMenuItem.Text = "Start paused";
this.startPausedToolStripMenuItem.Click += new System.EventHandler(this.startPausedToolStripMenuItem_Click);
//
// frameSkipToolStripMenuItem
//
this.frameSkipToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.miLimitFramerate,
this.miDisplayVsync,
this.toolStripMenuItem3,
this.miAutoMinimizeSkipping,
this.miFrameskip0,
this.miFrameskip1,
this.miFrameskip2,
this.miFrameskip3,
this.miFrameskip4,
this.miFrameskip5,
this.miFrameskip6,
this.miFrameskip7,
this.miFrameskip8,
this.miFrameskip9,
this.toolStripMenuItem5,
this.miSpeed50,
this.miSpeed75,
this.miSpeed100,
this.miSpeed150,
this.miSpeed200});
this.frameSkipToolStripMenuItem.Name = "frameSkipToolStripMenuItem";
this.frameSkipToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.frameSkipToolStripMenuItem.Text = "Speed/Skip";
this.frameSkipToolStripMenuItem.DropDownOpened += new System.EventHandler(this.frameSkipToolStripMenuItem_DropDownOpened);
//
// miLimitFramerate
//
this.miLimitFramerate.Name = "miLimitFramerate";
this.miLimitFramerate.Size = new System.Drawing.Size(192, 22);
this.miLimitFramerate.Text = "Limit Framerate";
this.miLimitFramerate.Click += new System.EventHandler(this.miLimitFramerate_Click);
//
// miDisplayVsync
//
this.miDisplayVsync.Name = "miDisplayVsync";
this.miDisplayVsync.Size = new System.Drawing.Size(192, 22);
this.miDisplayVsync.Text = "Display VSync";
this.miDisplayVsync.Click += new System.EventHandler(this.miDisplayVsync_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(189, 6);
//
// miAutoMinimizeSkipping
//
this.miAutoMinimizeSkipping.Name = "miAutoMinimizeSkipping";
this.miAutoMinimizeSkipping.Size = new System.Drawing.Size(192, 22);
this.miAutoMinimizeSkipping.Text = "Auto-minimize skipping";
this.miAutoMinimizeSkipping.Click += new System.EventHandler(this.miAutoMinimizeSkipping_Click);
//
// miFrameskip0
//
this.miFrameskip0.Name = "miFrameskip0";
this.miFrameskip0.Size = new System.Drawing.Size(192, 22);
this.miFrameskip0.Text = "0 (never skip)";
this.miFrameskip0.Click += new System.EventHandler(this.miFrameskip0_Click);
//
// miFrameskip1
//
this.miFrameskip1.Name = "miFrameskip1";
this.miFrameskip1.Size = new System.Drawing.Size(192, 22);
this.miFrameskip1.Text = "1";
this.miFrameskip1.Click += new System.EventHandler(this.miFrameskip1_Click);
//
// miFrameskip2
//
this.miFrameskip2.Name = "miFrameskip2";
this.miFrameskip2.Size = new System.Drawing.Size(192, 22);
this.miFrameskip2.Text = "2";
this.miFrameskip2.Click += new System.EventHandler(this.miFrameskip2_Click);
//
// miFrameskip3
//
this.miFrameskip3.Name = "miFrameskip3";
this.miFrameskip3.Size = new System.Drawing.Size(192, 22);
this.miFrameskip3.Text = "3";
this.miFrameskip3.Click += new System.EventHandler(this.miFrameskip3_Click);
//
// miFrameskip4
//
this.miFrameskip4.Name = "miFrameskip4";
this.miFrameskip4.Size = new System.Drawing.Size(192, 22);
this.miFrameskip4.Text = "4";
this.miFrameskip4.Click += new System.EventHandler(this.miFrameskip4_Click);
//
// miFrameskip5
//
this.miFrameskip5.Name = "miFrameskip5";
this.miFrameskip5.Size = new System.Drawing.Size(192, 22);
this.miFrameskip5.Text = "5";
this.miFrameskip5.Click += new System.EventHandler(this.miFrameskip5_Click);
//
// miFrameskip6
//
this.miFrameskip6.Name = "miFrameskip6";
this.miFrameskip6.Size = new System.Drawing.Size(192, 22);
this.miFrameskip6.Text = "6";
this.miFrameskip6.Click += new System.EventHandler(this.miFrameskip6_Click);
//
// miFrameskip7
//
this.miFrameskip7.Name = "miFrameskip7";
this.miFrameskip7.Size = new System.Drawing.Size(192, 22);
this.miFrameskip7.Text = "7";
this.miFrameskip7.Click += new System.EventHandler(this.miFrameskip7_Click);
//
// miFrameskip8
//
this.miFrameskip8.Name = "miFrameskip8";
this.miFrameskip8.Size = new System.Drawing.Size(192, 22);
this.miFrameskip8.Text = "8";
this.miFrameskip8.Click += new System.EventHandler(this.miFrameskip8_Click);
//
// miFrameskip9
//
this.miFrameskip9.Name = "miFrameskip9";
this.miFrameskip9.Size = new System.Drawing.Size(192, 22);
this.miFrameskip9.Text = "9";
this.miFrameskip9.Click += new System.EventHandler(this.miFrameskip9_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(189, 6);
//
// miSpeed50
//
this.miSpeed50.Name = "miSpeed50";
this.miSpeed50.Size = new System.Drawing.Size(192, 22);
this.miSpeed50.Text = "Speed 50%";
this.miSpeed50.Click += new System.EventHandler(this.miSpeed50_Click);
//
// miSpeed75
//
this.miSpeed75.Name = "miSpeed75";
this.miSpeed75.Size = new System.Drawing.Size(192, 22);
this.miSpeed75.Text = "Speed 75%";
this.miSpeed75.Click += new System.EventHandler(this.miSpeed75_Click);
//
// miSpeed100
//
this.miSpeed100.Name = "miSpeed100";
this.miSpeed100.Size = new System.Drawing.Size(192, 22);
this.miSpeed100.Text = "Speed 100%";
this.miSpeed100.Click += new System.EventHandler(this.miSpeed100_Click);
//
// miSpeed150
//
this.miSpeed150.Name = "miSpeed150";
this.miSpeed150.Size = new System.Drawing.Size(192, 22);
this.miSpeed150.Text = "Speed 150%";
this.miSpeed150.Click += new System.EventHandler(this.miSpeed150_Click);
//
// miSpeed200
//
this.miSpeed200.Name = "miSpeed200";
this.miSpeed200.Size = new System.Drawing.Size(192, 22);
this.miSpeed200.Text = "Speed 200%";
this.miSpeed200.Click += new System.EventHandler(this.miSpeed200_Click);
//
// toolsToolStripMenuItem
//
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -965,14 +1151,14 @@
//
this.helpToolStripMenuItem1.Enabled = false;
this.helpToolStripMenuItem1.Name = "helpToolStripMenuItem1";
this.helpToolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
this.helpToolStripMenuItem1.Size = new System.Drawing.Size(114, 22);
this.helpToolStripMenuItem1.Text = "&Help";
this.helpToolStripMenuItem1.Click += new System.EventHandler(this.helpToolStripMenuItem1_Click);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(114, 22);
this.aboutToolStripMenuItem.Text = "&About";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
@ -1102,6 +1288,27 @@
private System.Windows.Forms.ToolStripMenuItem rAMPokeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveWindowPositionToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem startPausedToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem frameSkipToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem miDisplayVsync;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem miAutoMinimizeSkipping;
private System.Windows.Forms.ToolStripMenuItem miFrameskip0;
private System.Windows.Forms.ToolStripMenuItem miFrameskip1;
private System.Windows.Forms.ToolStripMenuItem miFrameskip2;
private System.Windows.Forms.ToolStripMenuItem miFrameskip3;
private System.Windows.Forms.ToolStripMenuItem miFrameskip4;
private System.Windows.Forms.ToolStripMenuItem miFrameskip5;
private System.Windows.Forms.ToolStripMenuItem miFrameskip6;
private System.Windows.Forms.ToolStripMenuItem miFrameskip7;
private System.Windows.Forms.ToolStripMenuItem miFrameskip8;
private System.Windows.Forms.ToolStripMenuItem miFrameskip9;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
private System.Windows.Forms.ToolStripMenuItem miSpeed50;
private System.Windows.Forms.ToolStripMenuItem miSpeed75;
private System.Windows.Forms.ToolStripMenuItem miSpeed100;
private System.Windows.Forms.ToolStripMenuItem miSpeed150;
private System.Windows.Forms.ToolStripMenuItem miSpeed200;
private System.Windows.Forms.ToolStripMenuItem miLimitFramerate;
}
}

View File

@ -0,0 +1,382 @@
using System;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using BizHawk.Core;
using BizHawk.Emulation.Consoles.Sega;
using BizHawk.Emulation.Consoles.TurboGrafx;
using BizHawk.Emulation.Consoles.Calculator;
using BizHawk.Emulation.Consoles.Gameboy;
using BizHawk.Emulation.Consoles.Nintendo;
namespace BizHawk.MultiClient
{
partial class MainForm
{
private void rAMPokeToolStripMenuItem_Click(object sender, EventArgs e)
{
RamPoke r = new RamPoke();
r.Show();
}
private void saveWindowPositionToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SaveWindowPosition ^= true;
}
private void startPausedToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.StartPaused ^= true;
}
private void luaConsoleToolStripMenuItem_Click(object sender, EventArgs e)
{
var window = new BizHawk.MultiClient.tools.LuaWindow();
window.Show();
}
private void miLimitFramerate_Click(object sender, EventArgs e)
{
Global.Config.LimitFramerate ^= true;
}
private void miDisplayVsync_Click(object sender, EventArgs e)
{
Global.Config.DisplayVSync ^= true;
Global.RenderPanel.Resized = true;
}
private void miAutoMinimizeSkipping_Click(object sender, EventArgs e)
{
Global.Config.AutoMinimizeSkipping ^= true;
}
private void miFrameskip0_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 0; }
private void miFrameskip1_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 1; }
private void miFrameskip2_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 2; }
private void miFrameskip3_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 3; }
private void miFrameskip4_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 4; }
private void miFrameskip5_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 5; }
private void miFrameskip6_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 6; }
private void miFrameskip7_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 7; }
private void miFrameskip8_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 8; }
private void miFrameskip9_Click(object sender, EventArgs e) { Global.Config.FrameSkip = 9; }
private void miSpeed50_Click(object sender, EventArgs e) { SetSpeedPercent(50); }
private void miSpeed75_Click(object sender, EventArgs e) { SetSpeedPercent(75); }
private void miSpeed100_Click(object sender, EventArgs e) { SetSpeedPercent(100); }
private void miSpeed150_Click(object sender, EventArgs e) { SetSpeedPercent(150); }
private void miSpeed200_Click(object sender, EventArgs e) { SetSpeedPercent(200); }
private void pauseWhenMenuActivatedToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.PauseWhenMenuActivated ^= true;
}
private void soundToolStripMenuItem_Click(object sender, EventArgs e)
{
SoundConfig s = new SoundConfig();
s.ShowDialog();
}
private void zoomMenuItem_Click(object sender, EventArgs e)
{
if (sender == x1MenuItem) Global.Config.TargetZoomFactor = 1;
if (sender == x2MenuItem) Global.Config.TargetZoomFactor = 2;
if (sender == x3MenuItem) Global.Config.TargetZoomFactor = 3;
if (sender == x4MenuItem) Global.Config.TargetZoomFactor = 4;
if (sender == x5MenuItem) Global.Config.TargetZoomFactor = 5;
if (sender == mzMenuItem) Global.Config.TargetZoomFactor = 10;
x1MenuItem.Checked = Global.Config.TargetZoomFactor == 1;
x2MenuItem.Checked = Global.Config.TargetZoomFactor == 2;
x3MenuItem.Checked = Global.Config.TargetZoomFactor == 3;
x4MenuItem.Checked = Global.Config.TargetZoomFactor == 4;
x5MenuItem.Checked = Global.Config.TargetZoomFactor == 5;
mzMenuItem.Checked = Global.Config.TargetZoomFactor == 10;
FrameBufferResized();
}
private void enableFMChipToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsEnableFM ^= true;
}
private void overclockWhenKnownSafeToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsAllowOverlock ^= true;
}
private void forceStereoSeparationToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsForceStereoSeparation ^= true;
}
private void recordMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
RecordMovie r = new RecordMovie();
r.ShowDialog();
}
private void playMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
PlayMovie p = new PlayMovie();
p.ShowDialog();
}
private void stopMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void playFromBeginningToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void RAMWatchToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRamWatch();
}
private void rAMSearchToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRamSearch();
}
private void autoloadMostRecentToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateAutoLoadRecentRom();
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.RecentRoms.Clear();
}
private void selectSlot1ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 1;
SaveSlotSelectedMessage();
}
private void selectSlot2ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 2;
SaveSlotSelectedMessage();
}
private void selectSlot3ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 3;
SaveSlotSelectedMessage();
}
private void selectSlot4ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 4;
SaveSlotSelectedMessage();
}
private void selectSlot5ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 5;
SaveSlotSelectedMessage();
}
private void selectSlot6ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 6;
SaveSlotSelectedMessage();
}
private void selectSlot7ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 7;
SaveSlotSelectedMessage();
}
private void selectSlot8ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 8;
SaveSlotSelectedMessage();
}
private void selectSlot9ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 9;
SaveSlotSelectedMessage();
}
private void selectSlot10ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 0;
SaveSlotSelectedMessage();
}
private void previousSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
if (SaveSlot == 0) SaveSlot = 9; //Wrap to end of slot list
else if (SaveSlot > 9) SaveSlot = 9; //Meh, just in case
else SaveSlot--;
SaveSlotSelectedMessage();
}
private void nextSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
if (SaveSlot >= 9) SaveSlot = 1; //Wrap to beginning of slot list
else SaveSlot++;
SaveSlotSelectedMessage();
}
private void saveToCurrentSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveState("QuickSave" + SaveSlot.ToString());
}
private void loadCurrentSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadState("QuickSave" + SaveSlot.ToString());
}
private void closeROMToolStripMenuItem_Click(object sender, EventArgs e)
{
CloseGame();
Global.Emulator = new NullEmulator();
Text = "BizHawk";
}
private void saveStateToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Sound.StopSound();
var frm = new NameStateForm();
frm.ShowDialog(this);
if (frm.OK)
SaveState(frm.Result);
Global.Sound.StartSound();
}
private void powerToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRom(CurrentlyOpenRom);
}
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Global.Emulator.ControllerDefinition.BoolButtons.Contains("Reset"))
Global.Emulator.Controller.ForceButton("Reset");
}
private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
{
if (EmulatorPaused == true)
UnpauseEmulator();
else
PauseEmulator();
}
private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
{
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
new AboutBox().ShowDialog();
}
private void controllersToolStripMenuItem_Click(object sender, EventArgs e)
{
InputConfig i = new InputConfig();
i.ShowDialog();
}
private void hotkeysToolStripMenuItem_Click(object sender, EventArgs e)
{
BizHawk.MultiClient.tools.HotkeyWindow h = new BizHawk.MultiClient.tools.HotkeyWindow();
h.ShowDialog();
}
private void displayFPSToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayFPS ^= true;
}
private void displayFrameCounterToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayFrameCounter ^= true;
}
private void displayInputToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayInput ^= true;
}
private void displayLagCounterToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayLagCounter ^= true;
}
private void screenshotF12ToolStripMenuItem_Click(object sender, EventArgs e)
{
TakeScreenshot();
}
private void savestate1toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave1"); }
private void savestate2toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave2"); }
private void savestate3toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave3"); }
private void savestate4toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave4"); }
private void savestate5toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave5"); }
private void savestate6toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave6"); }
private void savestate7toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave7"); }
private void savestate8toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave8"); }
private void savestate9toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave9"); }
private void savestate0toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave0"); }
private void loadstate1toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave1"); }
private void loadstate2toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave2"); }
private void loadstate3toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave3"); }
private void loadstate4toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave4"); }
private void loadstate5toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave5"); }
private void loadstate6toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave6"); }
private void loadstate7toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave7"); }
private void loadstate8toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave8"); }
private void loadstate9toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave9"); }
private void loadstate0toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave0"); }
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
if (RamWatch1.AskSave())
Close();
}
private void openROMToolStripMenuItem_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog();
ofd.InitialDirectory = Global.Config.LastRomPath;
ofd.Filter = "Rom Files|*.SMS;*.GG;*.SG;*.PCE;*.SGX;*.GB;*.BIN;*.SMD;*.ZIP;*.7z|Master System|*.SMS;*.GG;*.SG;*.ZIP;*.7z|PC Engine|*.PCE;*.SGX;*.ZIP;*.7z|Gameboy|*.GB;*.ZIP;*.7z|Archive Files|*.zip;*.7z|All Files|*.*";
ofd.RestoreDirectory = true;
Global.Sound.StopSound();
var result = ofd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return;
var file = new FileInfo(ofd.FileName);
Global.Config.LastRomPath = file.DirectoryName;
LoadRom(file.FullName);
}
}
}

View File

@ -19,22 +19,17 @@ namespace BizHawk.MultiClient
private Control renderTarget;
private RetainedViewportPanel retainedPanel;
private string CurrentlyOpenRom;
private int SaveSlot = 0; //Saveslot sytem
//the currently selected savestate slot
private int SaveSlot = 0;
//runloop control
struct MainLoopData
{
public int lastskiprate;
public int framestoskip;
public int FrameAdvanceDelay;
public bool runloop_frameProgress;
public bool skipnextframe;
public bool exit;
}
MainLoopData mainLoopData = new MainLoopData();
bool exit;
bool runloop_frameProgress;
DateTime FrameAdvanceTimestamp = DateTime.MinValue;
public bool EmulatorPaused;
Throttle throttle;
bool runloop_frameadvance;
Throttle throttle = new Throttle();
//For handling automatic pausing when entering the menu
private bool wasPaused = false;
@ -139,15 +134,17 @@ namespace BizHawk.MultiClient
if (Global.Config.StartPaused)
PauseEmulator();
}
//TODO - pick the actual correct throttle rate based on the platform and configuration
//(and later we will need to modify it at runtime)
throttle = new Throttle(30);
void SetSpeedPercent(int value)
{
Global.Config.SpeedPercent = value;
throttle.SetSpeedPercent(value);
}
protected override void OnClosed(EventArgs e)
{
mainLoopData.exit = true;
exit = true;
base.OnClosed(e);
}
@ -159,13 +156,15 @@ namespace BizHawk.MultiClient
CheckHotkeys();
StepRunLoop_Core();
//StepRunLoop_Throttle(true, -1);
StepRunLoop_Core();
if(!IsNullEmulator())
StepRunLoop_Throttle();
Render();
CheckMessages();
if (mainLoopData.exit)
if (exit)
break;
Thread.Sleep(0);
}
@ -431,6 +430,17 @@ namespace BizHawk.MultiClient
new BizHawk.Emulation.Consoles.Gameboy.Debugger(Global.Emulator as Gameboy).Show();
}
//setup the throttle based on platform's specifications
//(one day later for some systems we will need to modify it at runtime as the display mode changes)
{
object o = Global.Emulator.Query(EmulatorQuery.VsyncRate);
if (o is double)
throttle.SetCoreFps((double)o);
else throttle.SetCoreFps(60);
SetSpeedPercent(Global.Config.SpeedPercent);
}
CurrentlyOpenRom = path;
return true;
}
@ -506,13 +516,6 @@ namespace BizHawk.MultiClient
LoadRom(CurrentlyOpenRom);
}
//TODO - fast forward is handled by disabling the throttle
if (Global.ClientControls["Fast Forward"])
{
Global.Emulator.FrameAdvance(false);
Global.Emulator.FrameAdvance(false);
Global.Emulator.FrameAdvance(false);
}
if (Global.ClientControls["Screenshot"])
{
Global.ClientControls.UnpressButton("Screenshot");
@ -554,52 +557,57 @@ namespace BizHawk.MultiClient
}
}
void StepRunLoop_Throttle()
{
throttle.signal_fastForward = Global.ClientControls["Fast Forward"];
throttle.signal_frameAdvance = runloop_frameadvance;
throttle.signal_continuousframeAdvancing = runloop_frameProgress;
throttle.Step(true, -1);
}
void StepRunLoop_Core()
{
//TODO - this method can't depend on that value of 60. it may run too quickly.
//this method needs to be refactored anyway since I'm not sure that it is where all this belongs
bool runFrame = false;
runloop_frameadvance = false;
DateTime now = DateTime.Now;
double frameAdvanceTimestampDelta = (now - FrameAdvanceTimestamp).TotalMilliseconds;
bool frameProgressTimeElapsed = Global.Config.FrameProgressDelayMs < frameAdvanceTimestampDelta;
//handle unpress of frame advance: do we need to deactivate FrameProgress?
if (!Global.ClientControls.IsPressed("Frame Advance"))
if (Global.ClientControls["Frame Advance"])
{
if (mainLoopData.runloop_frameProgress)
{
mainLoopData.runloop_frameProgress = false;
PauseEmulator();
}
mainLoopData.FrameAdvanceDelay = 60;
}
//handle normal frame advance: either countdown, or the initial trigger (which necessitates a pause)
if (Global.ClientControls["Frame Advance"] && mainLoopData.FrameAdvanceDelay > 0)
{
if (mainLoopData.FrameAdvanceDelay == 60)
//handle the initial trigger of a frame advance
if (FrameAdvanceTimestamp == DateTime.MinValue)
{
if (!EmulatorPaused) PauseEmulator();
runFrame = true;
mainLoopData.FrameAdvanceDelay--;
runloop_frameadvance = true;
FrameAdvanceTimestamp = now;
}
else
{
if (mainLoopData.FrameAdvanceDelay > 0)
mainLoopData.FrameAdvanceDelay--;
if (mainLoopData.FrameAdvanceDelay < 0)
mainLoopData.FrameAdvanceDelay = 0;
//handle the timed transition from countdown to FrameProgress
if (frameProgressTimeElapsed)
{
runFrame = true;
runloop_frameProgress = true;
UnpauseEmulator();
}
}
}
//frame advance: handle the timed transition from countdown to FrameProgress
if (Global.ClientControls["Frame Advance"] && mainLoopData.FrameAdvanceDelay == 0)
else
{
runFrame = true;
mainLoopData.runloop_frameProgress = true;
UnpauseEmulator();
//handle release of frame advance: do we need to deactivate FrameProgress?
if (runloop_frameProgress)
{
runloop_frameProgress = false;
PauseEmulator();
}
FrameAdvanceTimestamp = DateTime.MinValue;
}
if (!EmulatorPaused)
{
runFrame = true;
@ -614,13 +622,13 @@ namespace BizHawk.MultiClient
if (runFrame)
{
CaptureRewindState();
DoFrameAdvance();
Global.Emulator.FrameAdvance(!throttle.skipnextframe);
Global.Sound.UpdateSound(Global.Emulator.SoundProvider);
RamWatch1.UpdateValues();
RamSearch1.UpdateValues();
}
}
private bool wasMaximized = false;
private void TakeScreenshot()
{
var video = Global.Emulator.VideoProvider;
@ -665,227 +673,12 @@ namespace BizHawk.MultiClient
Global.RenderPanel.AddMessage("Loaded state: " + name);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
if (RamWatch1.AskSave())
Close();
}
private void openROMToolStripMenuItem_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog();
ofd.InitialDirectory = Global.Config.LastRomPath;
ofd.Filter = "Rom Files|*.SMS;*.GG;*.SG;*.PCE;*.SGX;*.GB;*.BIN;*.SMD;*.ZIP;*.7z|Master System|*.SMS;*.GG;*.SG;*.ZIP;*.7z|PC Engine|*.PCE;*.SGX;*.ZIP;*.7z|Gameboy|*.GB;*.ZIP;*.7z|Archive Files|*.zip;*.7z|All Files|*.*";
ofd.RestoreDirectory = true;
Global.Sound.StopSound();
var result = ofd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return;
var file = new FileInfo(ofd.FileName);
Global.Config.LastRomPath = file.DirectoryName;
LoadRom(file.FullName);
}
private void savestate1toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave1"); }
private void savestate2toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave2"); }
private void savestate3toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave3"); }
private void savestate4toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave4"); }
private void savestate5toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave5"); }
private void savestate6toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave6"); }
private void savestate7toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave7"); }
private void savestate8toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave8"); }
private void savestate9toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave9"); }
private void savestate0toolStripMenuItem_Click(object sender, EventArgs e) { SaveState("QuickSave0"); }
private void loadstate1toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave1"); }
private void loadstate2toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave2"); }
private void loadstate3toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave3"); }
private void loadstate4toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave4"); }
private void loadstate5toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave5"); }
private void loadstate6toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave6"); }
private void loadstate7toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave7"); }
private void loadstate8toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave8"); }
private void loadstate9toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave9"); }
private void loadstate0toolStripMenuItem_Click(object sender, EventArgs e) { LoadState("QuickSave0"); }
private void saveStateToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Sound.StopSound();
var frm = new NameStateForm();
frm.ShowDialog(this);
if (frm.OK)
SaveState(frm.Result);
Global.Sound.StartSound();
}
private void powerToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRom(CurrentlyOpenRom);
}
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Global.Emulator.ControllerDefinition.BoolButtons.Contains("Reset"))
Global.Emulator.Controller.ForceButton("Reset");
}
private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
{
if (EmulatorPaused == true)
UnpauseEmulator();
else
PauseEmulator();
}
private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
{
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
new AboutBox().ShowDialog();
}
private void controllersToolStripMenuItem_Click(object sender, EventArgs e)
{
InputConfig i = new InputConfig();
i.ShowDialog();
}
private void hotkeysToolStripMenuItem_Click(object sender, EventArgs e)
{
BizHawk.MultiClient.tools.HotkeyWindow h = new BizHawk.MultiClient.tools.HotkeyWindow();
h.ShowDialog();
}
private void displayFPSToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayFPS ^= true;
}
private void displayFrameCounterToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayFrameCounter ^= true;
}
private void displayInputToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayInput ^= true;
}
private void displayLagCounterToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.DisplayLagCounter ^= true;
}
private void screenshotF12ToolStripMenuItem_Click(object sender, EventArgs e)
{
TakeScreenshot();
}
private void SaveSlotSelectedMessage()
{
Global.RenderPanel.AddMessage("Slot " + SaveSlot + " selected.");
}
private void selectSlot1ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 1;
SaveSlotSelectedMessage();
}
private void selectSlot2ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 2;
SaveSlotSelectedMessage();
}
private void selectSlot3ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 3;
SaveSlotSelectedMessage();
}
private void selectSlot4ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 4;
SaveSlotSelectedMessage();
}
private void selectSlot5ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 5;
SaveSlotSelectedMessage();
}
private void selectSlot6ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 6;
SaveSlotSelectedMessage();
}
private void selectSlot7ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 7;
SaveSlotSelectedMessage();
}
private void selectSlot8ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 8;
SaveSlotSelectedMessage();
}
private void selectSlot9ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 9;
SaveSlotSelectedMessage();
}
private void selectSlot10ToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveSlot = 0;
SaveSlotSelectedMessage();
}
private void previousSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
if (SaveSlot == 0) SaveSlot = 9; //Wrap to end of slot list
else if (SaveSlot > 9) SaveSlot = 9; //Meh, just in case
else SaveSlot--;
SaveSlotSelectedMessage();
}
private void nextSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
if (SaveSlot >= 9) SaveSlot = 1; //Wrap to beginning of slot list
else SaveSlot++;
SaveSlotSelectedMessage();
}
private void saveToCurrentSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveState("QuickSave" + SaveSlot.ToString());
}
private void loadCurrentSlotToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadState("QuickSave" + SaveSlot.ToString());
}
private void closeROMToolStripMenuItem_Click(object sender, EventArgs e)
{
CloseGame();
Global.Emulator = new NullEmulator();
Text = "BizHawk";
}
private void emulationToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
powerToolStripMenuItem.Enabled = !IsNullEmulator();
@ -898,10 +691,7 @@ namespace BizHawk.MultiClient
if (didMenuPause) pauseToolStripMenuItem.Checked = wasPaused;
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.RecentRoms.Clear();
}
private void UpdateAutoLoadRecentRom()
{
@ -917,11 +707,6 @@ namespace BizHawk.MultiClient
}
}
private void autoloadMostRecentToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateAutoLoadRecentRom();
}
private void fileToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
if (IsNullEmulator())
@ -1101,16 +886,6 @@ namespace BizHawk.MultiClient
RamSearch1.Focus();
}
private void RAMWatchToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRamWatch();
}
private void rAMSearchToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadRamSearch();
}
private int lastWidth = -1;
private int lastHeight = -1;
@ -1186,62 +961,7 @@ namespace BizHawk.MultiClient
}
}
private void zoomMenuItem_Click(object sender, EventArgs e)
{
if (sender == x1MenuItem) Global.Config.TargetZoomFactor = 1;
if (sender == x2MenuItem) Global.Config.TargetZoomFactor = 2;
if (sender == x3MenuItem) Global.Config.TargetZoomFactor = 3;
if (sender == x4MenuItem) Global.Config.TargetZoomFactor = 4;
if (sender == x5MenuItem) Global.Config.TargetZoomFactor = 5;
if (sender == mzMenuItem) Global.Config.TargetZoomFactor = 10;
x1MenuItem.Checked = Global.Config.TargetZoomFactor == 1;
x2MenuItem.Checked = Global.Config.TargetZoomFactor == 2;
x3MenuItem.Checked = Global.Config.TargetZoomFactor == 3;
x4MenuItem.Checked = Global.Config.TargetZoomFactor == 4;
x5MenuItem.Checked = Global.Config.TargetZoomFactor == 5;
mzMenuItem.Checked = Global.Config.TargetZoomFactor == 10;
FrameBufferResized();
}
private void enableFMChipToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsEnableFM ^= true;
}
private void overclockWhenKnownSafeToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsAllowOverlock ^= true;
}
private void forceStereoSeparationToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SmsForceStereoSeparation ^= true;
}
private void recordMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
RecordMovie r = new RecordMovie();
r.ShowDialog();
}
private void playMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
PlayMovie p = new PlayMovie();
p.ShowDialog();
}
private void stopMovieToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void playFromBeginningToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void viewToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
displayFPSToolStripMenuItem.Checked = Global.Config.DisplayFPS;
@ -1293,42 +1013,35 @@ namespace BizHawk.MultiClient
startPausedToolStripMenuItem.Checked = Global.Config.StartPaused;
}
private void pauseWhenMenuActivatedToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.PauseWhenMenuActivated ^= true;
}
private void soundToolStripMenuItem_Click(object sender, EventArgs e)
{
SoundConfig s = new SoundConfig();
s.ShowDialog();
}
private void MainForm_Load(object sender, EventArgs e)
{
}
private void rAMPokeToolStripMenuItem_Click(object sender, EventArgs e)
private void frameSkipToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
RamPoke r = new RamPoke();
r.Show();
miDisplayVsync.Checked = Global.Config.LimitFramerate;
miAutoMinimizeSkipping.Checked = Global.Config.AutoMinimizeSkipping;
miLimitFramerate.Checked = Global.Config.LimitFramerate;
miDisplayVsync.Checked = Global.Config.DisplayVSync;
miFrameskip0.Checked = Global.Config.FrameSkip == 0;
miFrameskip1.Checked = Global.Config.FrameSkip == 1;
miFrameskip2.Checked = Global.Config.FrameSkip == 2;
miFrameskip3.Checked = Global.Config.FrameSkip == 3;
miFrameskip4.Checked = Global.Config.FrameSkip == 4;
miFrameskip5.Checked = Global.Config.FrameSkip == 5;
miFrameskip6.Checked = Global.Config.FrameSkip == 6;
miFrameskip7.Checked = Global.Config.FrameSkip == 7;
miFrameskip8.Checked = Global.Config.FrameSkip == 8;
miFrameskip9.Checked = Global.Config.FrameSkip == 9;
miSpeed100.Checked = Global.Config.SpeedPercent == 100;
miSpeed150.Checked = Global.Config.SpeedPercent == 150;
miSpeed200.Checked = Global.Config.SpeedPercent == 200;
miSpeed75.Checked = Global.Config.SpeedPercent == 75;
miSpeed50.Checked = Global.Config.SpeedPercent == 50;
miAutoMinimizeSkipping.Enabled = !miFrameskip0.Checked;
if (!miAutoMinimizeSkipping.Enabled) miAutoMinimizeSkipping.Checked = true;
}
private void saveWindowPositionToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.SaveWindowPosition ^= true;
}
private void startPausedToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.StartPaused ^= true;
}
private void luaConsoleToolStripMenuItem_Click(object sender, EventArgs e)
{
BizHawk.MultiClient.tools.LuaWindow l = new BizHawk.MultiClient.tools.LuaWindow();
l.Show();
}
}
}

View File

@ -120,6 +120,9 @@
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>30</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>

View File

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
// Runtime Version:2.0.50727.3615
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -116,6 +116,12 @@ namespace BizHawk.MultiClient.Properties {
}
}
internal static System.IO.UnmanagedMemoryStream nothawk {
get {
return ResourceManager.GetStream("nothawk", resourceCulture);
}
}
internal static System.Drawing.Bitmap PCEngineController {
get {
object obj = ResourceManager.GetObject("PCEngineController", resourceCulture);

View File

@ -160,4 +160,432 @@
<data name="undo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\images\undo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="nothawk" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v
cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw
b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB
AQEBCQIAAAAAAAAAAAAAAHhiAAB4YgAAAAEAAQoPAgAAAHhiAAACUklGRnBiAABXQVZFZm10IBAAAAAB
AAEAIlYAACJWAAABAAgAZGF0YYBhAAB/f39/gICAgH9/f39/gICAgH9/f4CAgIB/f39/gICAf39/gIB/
f39/f39/f3+AgH9/f3+AgIB/f39/gICAf39/gICAgIB/f39/f3+AgICAf39/gICAgH9/f4CAgIB/f39/
gICAgH9/gICAgH9/f3+AgIB/f39/f4CAgIB/f3+AgIB/f39/gICAf3+AgIB/f39/gICAf39/gICAf39/
f4CAgH9/f3+AgH9/f4CAgH9/f3+AgIB/f3+AgICAf3+AgH9/f3+AgICAgICAgH9/f39/f3+AgICAf39/
gICAgH9/f3+AgH9/f3+AgICAf3+AgICAf39/gICAgICAf39/gICAgH9/f4CAgH9/f4CAgH9/f3+AgIB/
f3+AgICAf39/f39/f3+AgIB/gICAgH9/f4CAgH9/f4CAgIB/f3+AgIB/f3+AgIB/f3+AgICAf39/gICA
gH9/f3+AgIB/f39/f4CAgICAgICAgICAf39/f39/f3+AgICAf39/gICAgH9/f4CAgH9/f4CAgH9/f4CA
gICAf39/f3+AgIB/f3+AgICAf39/gICAf39/f4CAgH9/f4CAgH9/f4CAgIB/f3+AgICAf39/gICAgH9/
f4CAgH9/f3+AgIB/f39/f4CAgH9/f3+AgIB/f3+AgICAf39/f4CAgICAgIB/f3+AgIB/f39/gIB/f3+A
gIB/f3+AgIB/f39/gICAf3+AgICAf39/f4CAf3+AgICAgICAgIB/f3+AgH9/f3+AgICAgH9/f39/gIB/
f39/gICAgH9/gICAgH9/gICAf35+f39/f39/gIGBgYCBgYGBgIB/fXp4eH2Bg4OCg4WHh4R/e3p7fH19
fXx+gYSEgoB/f4GBgYB/f3+Af39+fXx8fn+BgYGBgoODgoB+fX1+fn9/fn6AgYGBgH+AgIGAgICAgICA
gH99fX5/gICAf4CAgYKBgH9/f39/f35+f3+AgICAgICAgIGBgH9/f39+f3+Af39/gICAf4CAgICAgH9/
f39/gICAgICAgH9/f39/f39/f3+AgH+AgYGAgIGCgH57eHp/g4KAfn+DhYaFgH18fn9/fXl4fYOFhIKB
gYKEhYWFgHNobHqDhIF+gYyVlYt/eHR1en58dnR6hIuKgnx9gIKEhIB+gYODg4F7dXV5fH+Afn+Fh4aF
gn9+gYF/gH16fH9+e3p4eYCFhoaGhIWIhYB9enZ3fH18fn5/goaFg4GAgIODgH9+fHt/fnx7fH1/goOE
hIOCgoJ/fXx6e31+f39/gYKBgoKAfoCAf4CBfn1/gH9/fn1+gIGBgYCBgoGAf399fH1/f4CBgYGCgoKC
g4F+fHp6e3x9f4CBgoODg4OEg4SGhn9vX2FyhZCTkIuIiYeDfnt4dXl8dnF1foiQjYWDh4yRiW5TVGmB
joyCg5Kgo5eBbWRlb3p9dXJ+kZmTh314eoCBgoaCeXR0dHmChYiLiYKBgoSJin5mVl93iYyDfIOYp6SR
emxpb3h7dGhpf5abkIJ8gYuOhnt0dHmAg31zbnF/jJGPiIOFiYiEeWddZneDiIWCiJSalYd3cG90e315
dHiEjY2FfXp9goaEgH+Ag4aFgHl1dXl8fHp8gomMiYSBgYWGgn15eHyCgnZlYW6BjpCMjJKbnpN9a2Nj
aXB0c3aDk5yaj4WAgYJ+d3Z3eXx/e3V1eH2EiouMi4mHhH15d3h7fn54amBqfouPjo+YpaaWfWlfXmBl
cHqEkpmUioSDiIyHfHFucnh6eXl8hJCZm45pSFFxhIeDhJm1u6WDaF1bXWFrc3uOoJ6LenqNnZiDbWdv
eHhzcHWGnKGFXFNrh5GIfICasq2RcF1ZYGt0c253lKypkXl2hI+Kd2psdHh5fH2DlZ+LZlZnf4uJgHyN
pKmWe2heYWx4eXF1jKetm4J0dnx6bmVqe4mPjYN7gZCbl4ZwX1tqe3xzb3uTqqyZgnZ3fHx0aWVrfI6V
joF8go2QhHRudoGGgXdydoGMjYeCgoWIiYeAcFhSZn2HiIiNn66qlXtqY2JnbG9vdYebo5qLgH5+fnZv
c3x+fHl4fIeTlY2DgIWOjXRNOlB0jpaRkqO2uaN/YlJRXGxyb3WIm6GYh3+FjY+Gd21sbnR5eHZ+j6Gq
l2Q/UHaKiX9/l7W8o31gVVdfbnl2epKknoZydo6emIJrZnF4d3Z5gZOcfFFQbIeVkYiTr72rg19OS1Rk
cGttjK23pYZ3h52dhmVUXGlvdICRmYhnYniJjYqDiaKypodmVVNXYHN7dIGnvbCQcml4iYl4aWpzd3h7
g5Gio3tQUnGKkIJzfqCypodqW1ljdYJ7dYeir6SGaWJrdXZ1fY2Rhn19f4iYoJJzU0pfeH94cHmavMKr
h2pkbHBsY1tlh6aploF4fYR+cnB7i5OKd21xgJSdlIFvX15udnBrdJCwv7KVeW5uaWBaXGd/nbCrk3xz
dHV2d3qAhoN5dX2JkZSPiIaDb04/UGqAlaSuvL+ri3BdTEVQZ3mCjpuemIyEhoyLgXZxdHNtbHWEmKme
aTxKdZGViH6Vv8unc1BFS15vb2h4nrSwlXVzkquhelRMXW55g5CYhmBXdIuOiYSNr8WxiGJOS1FWXWd0
kLG+qol7jaOihl9HUGRxfIyTeFNeiKGhloyYuMCca0w+PkpZaXN7msLUwJJ1gZeTc0s4SGN5k6iVYlB1
n6mYgoGgwrmGVkE+R1lrdnqJq8nKp3lqe4uDaVFQZHN+jZqioYNfYHR9gYOBkq2wmnpfU1FVaIGFhZ21
sZd2YWJzhId9d3d1d4ORnqaTXzxPdImHeXeWws2re1hJT2N3eW1ylLO4nXJVYYKVkoJ0c3p+f4OLlZJy
UFRtgoyGfYytu6iEZVdWYHB6d3qPo6maeF1edY2Xj4F6eXp8fXyCk5+UcEhDX3Z+hI+jvsq3kGpQRkxa
anR5iqKpmYJ4gZGWi3xzcGtlZ3KEnKyZYUBXfpGUiIKdwL6ZbE1CSl9wdXmMoaeeiHqKpaiPaEtLX3F/
kZ+KWkxylJaLhI+30rmCVUNCR05cboCctryrjHyOpqB9VUBMZHKAlpRlSnCfrKGPiKLFuoRRQT43PVd9
m6y1tK6di4yWi2xJOkpsiJyWZjpWmsC7m3+TxMiUVjMvPVJia22Es9bXtId2iZqHWTExUXKImqaMW1uM
raSNfoy1wphdPTtIV2NweIGjydO4iWt5k45sQzJMcIOXr6d4WGyPmYl2d5e+u4ldT05RXGt3fYupw8Kg
cFtvh4dyXl1rdXuJmKSvnmhJWnB9hn55lLO1mnRbUlVqhIh7hJylmn5hW3KRopmBbWdsfpKdl3tSRWaI
joJ1fabPyZhlTEtZa3Nwbn+iuq6IYllykpyNenBzeXd0eYieqpdmQUlrg4V/haLEw6B4XlFSY3NzbHWP
o6GJc3qUpJ6Fa2Nrbmxyf5KjlGBCWXuOlZOYtMizhl5JQUZUZ3J9mLGxoYyAjKCdf15MUWFsdIKarZxs
V2uAiY+QlKy4nnRYSj8/V4SlppaMkJeZm5eJdmNUVmd5jJd1QEuIrqych4+70KptRjw5PE9tgYycr7q0
oZaXlIFdOjlYdIiVfUxRi7W6poqLtsqkZzwvMD1ZeoyMlKi7vKyblZF9WTk1UXWJelFKea/IxaqSosCy
e0QnJDlUZ294lcHf0qWEhZKSeUwqMlRxh5mYd2GBqrGdh4Sfu6p1RDZAUWBnanaey9a+lXJ4l5p7UTdA
XnSDlaOTbmeInI9/f46tvqBrT05SVFxrd4KbusOwinB5kZFzVE1ecHV5h5uqnnRcaXuGj4yHlqWbg2lU
TlZnfIaGlK61n39rbHeBgnlvbGxwgpaio45kT2WAiIF1eZm4t5ZtU1Jebnx+eYSjtKWAXVVsjJeKeHF4
hIeAfoeYn4pfQkxofoiJj6jDvpt0XFNWXWlydH2Top6MfH2Pm5N8aWlvcXF0fZKnm2c/T3iQlZGSp722
kWZMQ0dZbniAlayqloR7hZqeh2ZWXWtwcXiIorGSWk1mfo6VjZGstZhwVktLVnKTno58e4iWmZSSjoV0
Y19pd4SRg1ZHcJWakoiPtNC7hltKREFMZHqDjp2nqJ+VlpmQd1hKVmp4hI12UFyOq6aWipW1vJhlSEFG
VGVzfYKPo7OyoZWVkoFgQj9WcYeWhllUiLOwmIKGrMasckU6RVdiZmh3mru/rZKFk6adckY5SVxoc4eg
nn94j5mRioWInKSLaFVSVVtmdH+SrLmyl3Nsh5uRdFNKX3F1eoWZsKx+WF5zgIeEgpSrqZFzWUpPYXOA
ipyvr5h5aniLjX1pYWl1enl6hJmxsolSQ1x5hH54irDBrIJfUVNecoKDhpaloopuZHKFjId8dXZ3dHmE
jpejoXxKQGF7fnyAkbPErIVqXFlga3J0fJCkpI90anmMkINzcnt9d3Z6gYuZoZp/WEZYcHuBhZGrvLGU
dmFZXmhvcneDkpiPf3qGlpiLe3BtbXF1eYCNnKCFV0ZgfoqKiJKtvaqDZVdSVWFve4iWnp6RgH6NlY15
ZFxod3l3eoOTpKyheEdBYXmBhYaSrbmlg2dYVmJ7j49+bWl2iZOaoJySgW5na25yfYqPgGFWbIGGiZCd
tL+qgmBTUVJZa3yHjpCPj46RnqWagmhaXGRnbHmOnY5uZnqKkZKMkKOplXVaTEtWa4GOkZOVlY+Hi5SU
inReW2VsdoeVkHVhb4aMh4SJnraykXBcUU1SYnJ/kaWroYx6gJOYhm9fYW5ycXWBkqaieVNadIaNi4iX
ra2TcVZJTmBzgIqcqKGOe296j5eJc2Jjcn59en6NoKWIXEladYeMjJSnsKKGaldQV2h4gIiapJuIeXeC
jYp8bWlvd3t+gIOLlp6djmtJSWN3gIWKlq23poVsY15eaHZ6fImWlo+EeXqEioeCfHNwc3l+gYaOlJOJ
cFZXaHR+ipSgra2cgmtdVVZidH2Fl6aklYV4dXt/enNycnJ3gYiOkZGNi4yMflo9RmaClZyYobGwmHtj
U1BccYCDg4qUm5WDeXyFi4Z3a2hrdoOKiYmNlZqSc0tBW3yNk5GSoq+jhGlcWF9xgoWDiY6Oi4WBhYiC
d25tc3yBhYaFh4uPkY98Vz9Sc4iUl5Ocr6+UdF1RWXaPj3tmZXmQlZCPk5WPgXFqbHB3f4GEjYxuUldu
gpWkqKuuooVpWU5IVXaQk4qFhYyVlpWTi31wZ2RmaG9+j5qdjm5daXuDiYyRoauZc1tdaG91e36AiZCO
hoGDjpaRgGtjbHh6eXyIlpFwWWR4hY+TlaKsoodrV01NXHaKj5KXl4+Hho2Sjn9tYmNmaXOBjZypnHRa
YnJ+hISIm6ykiW1bVlljdYaTn6GYh3RvgJCOgG9kZ3R9f4CGj5umoX9SQVZve4KJlai1rJBzYVpbZnV9
gIiUmZOFenyFiIB2c3NxcnqCh4yQkI6MiYV0U0NWcYWUmJair6qUe2RUVGN0fHp7iZqgloR6foiKgHBo
aHF9hoiEhIqRlpOAXUZUdouOiIeWq66YeGJYWmh6gX5/jJyhlH1tbXmHiHxxbXB7iY+Lh4mKhX5+hohz
UUpkgZGUjo6eq6WOdGBYXWx8fnZ6jp+fjXh0gIuKfW5pbXeCiomDg4iNj46GcFBJY36KjY2SpbGmjHBe
WF1qeX57f4uXmo+DgYaIgXNrbnN2fIGCgYOIjI6Rk4hmS1NwhYuIiJapqZV8Z1tdb4eTiXdsdIePioeK
j46Edm9ucHV6foGIlpyJYExdeo+Yl5GYoJiAaFlTXXeTnZF/d4KOi4KChIR/dWxscXiCjZCOkZiPbEtM
Y3yQmJWYoJyLeXFtbHJ8gHlwb3uJi4mPlpWOgHJwc3N0eoKJjX5hV2l+i5OYnaepl3xoXFddaXZ+g4iQ
lZGJh4yRjoBvZmlucnd7g5Ghn4BcWGyAiomFjp+jlH5tYFthcICLkpOPioF4fIqQiHptanN8fn6ChoyU
mI1wUU5lfIiPkZajqp2DbFxVWmx+hYSLmJ+bjHt0eXx5dXNvbXSCjpKRj42HgHx+g3xfSFV2jZWTj5em
qZqBaVpVX3R/eXaClqSfinp8homAcmdjaXiGiYeGi5GUkY2GcVNKYHmCg4WPoq2kkHxuZWVteH14eIWT
lIl6dHyKkIyCd29scnyCg4OGiISBgYaMj4NjTVt1hImIhZOqsaCGbFpZZ3V5c3KDm6SYgXN4iZOMe25m
aHSAgoCBipOUjomJhW5RTGJ5hoyOlKKpoY97a19danl6c3aGlZiOgX+HkpKHeGpiZHB6fYCHkJSSioKA
houJgG1TSl96homKlKm5sZR2Y1xcZG91dnuFkZeRiIyVkoRzZmVqcXZ8gYaLkZWam4xmRktnfYeJh5Oq
saCGb2BbZnqEfXJzgZGVjYeKjIqAcmxvdHuAgHx8g46Wlo1yVFNvho+NhoufpZB0ZmVue4J/eHV9i5WR
gXh+iIuBcGlzgIaEgX+FkZmTc0pFZoaSk46RoaqZfGdgZW51eXh2f4+ZlYd/ho+NfWhhbHl9fn6BiJKa
nJBvT09rgoiEgYyjrJ6Fb2JgaHV+f36Fj5CJf36HkY5+bmhrdX6Bfn6EjpSVj4JrV1pufoWGh5CfpZmD
cGRiaHV/gH2DkpuUgnV0fYeJgnhybm91f4aJjJCQh3x2eX+Fh4FwXVttgIiHhY+ntquPcmBbX2Vqa218
laimk4ODjZKHdWVfYmhvdn6Jl6Kil4d8en6Ae29dT1l0h4yMjpistqiKcGJeYGRoaWt5kKCil4eDjJaT
hHRnYGBjaG57jZ2jnpSNiYV/d3Bsa2lgW2h9jJWdoqiroo54Z1pWWmFpcHyPoKehl5CKhHpvam1vbm1v
dYGOmJuXkIiDfnhzb21xeH19dW52iJOVko+QlZOGdWdfXmRveH6FkZ6moZGBeHVybm1wdXp+goSFiI2O
ioR+e3p6eHh4eXt+gYSJj4x6ZWV3hoqIhYmVmpB9bmViaHWCh4eJjpKOg36EiYd+cmxtcHN5f4OHio2O
ioSDg4B7dnN1eoCAdGNkfJGYlo+OmJ+UfmldXGJud3p8hpWgn5KHhYmIfGpeX2hxeH2CipWdnJKGfnx7
dnFub3FsaHKEkJSVlJifmol3a2RiZGtzeX+Ik5qXkIyMi4R3amZpbG90e4OKkJOSj4uIg312b2tudHqA
fXNxgZOZlo6IjJKMfGxiYmhxeX5/hJGhpJeGfHt9eW5mZ295gIKChYySk4+GfHl7e3h1cHB3gIeMjIFy
c4KLiYN+gIyTjH1xbW9zd3p7e4GQnJyPgHp6fHhua3N9goKBgYWMkY+If3l4d3Vxb3J7hYmIhoaKjYyH
gHt5eHFkY3GAiY2NkJiclId7cWtqbXFzdX2JlJaPh4OChIF5dXh4dXR0d3+HjZCQi4aAe3h1cXB1en6B
hIaIjI2Lh4J+fHx0Z2JsfYeKioyUmpeLfnVvbG1wcnJ2gZCXk4mEhYaEfHRzdnp9fHt6fIGHiomIh4eF
f3hycXN4fX+AgoWJioiGg4GBfnl1dXd8gH95d3+Jj4yGgoWJiIB2cG90eXt9fYCHkJKMhH9+f314c3N3
fYGDg4KDhYeGgn18foCAfHd4fICCgoKDhYWDgH16en2Af319foCCgoGBgoSEg4B/fXl0dHl/goSGh4qL
h4N+eXZ2eHp8fX+Dh4iFgoCBgYB9ent9f4CAgH9/f4B/f3+BgoOEgn59f39+fHx8foCCg4KBgoOBf359
fH5/f39/gIGCgH9+fn5/f4CAgICBgYGAgIB/fXx7ent9gYWHh4eHhoN/e3d2d3l7fH+EiIqJhoJ/fn19
e3p6fH+AgH+AgYKCgoCAf4CAf359fX5/f39+f3+BgoODgoKCgH57e3t9fn+AgoOEhISDgX99fHt6eXt+
gIKDg4OEhYOBf318fHx7e3t8foGDhIWFhYWFg4F+e3l4eHl6fH+ChYiIh4WDgX99enh5e31/f35/goSF
hIKBgH9+fXx8fH5/f39/gIKDgoGAf39/f39+fn5+gICAgIGBgYGAf4CAgICAf35/f4CAgICAgIB/f39/
f4B/f35/gICBgYGBgIB/fn5+fn5+f4CAgIGCgoCAf35+fn5/f4CAgYGBgYGAgH99fHx9f4CBgoKCgoGA
gH99fHx8fX5/gYKDg4KBgIB/fn19fX1+f4CBgYGBgYCAf35+f4CAf3+Af39/fn1+f4CBg4SDgoF/fn18
fH1+foCBgoKCgoKCgH9+fn5+fX1/gICAgIB/gIGBgYB/f4CAgH9+fn5/f3+Af4CAgYGAgICAgH9/f3+A
gIB/f35+fn5/gIGBgYKBgYB/fn5+fn59fX6AgYKCgoGBgYB/fn59fn+AgICAf39/gICBgYGBgH9+fn19
fn+AgIGBgYGAgH9/f39/f3+AgICAgICAgIB/f39+f39/gIGBgYGAf35+fn5+f4CAgICBgYCAf39+f3+A
gICAgICAf39/gICAgH9/f4CAgIB/f39/gICAgIB/fn5/f39/gICAgICAgYGBgH9+fXx8fX5/gYKDg4KC
gYB/fn59fH1+fn+BgoKCgoKBf35+fX19fn5/gIGBgYGAgICAgIB/f39/f35+fn+AgYGCgYGBgYB/fXx8
fX5/gICBgoKCgYGAf35+fX19fX6AgYGCgoKBgH9+fn5/f3+AgIB/f39/f4CBgYGAf39/f39/f4CAgIB/
f39/f3+AgICBgYB/f4CAf39/f39/fn5/gIGBgoGBgH9/f35+fn5/gICAgIGBgICAf39/gICAgH9/f4CA
gIB/fn5/f4CAgYGAgICAgICAf39+fn5+f4CBgoGAf35+f3+AgYGBgH9/f39/f39/f39/gIGCgYGAgH9/
f39/fn19fX6AgYKDgoKBgH9/fn5+fXx8fX+AgYKDg4KBgIB/f359fX19fn+AgoODgoF/f39+fn5+fn5+
f4CBgYGBgIB/f3+AgIB/fn1+f4CBgYGBgYGBgIB/f359fHx9f4GDhISDgoB/fn18fHx8fX6AgoOEg4OB
f35+fn19fX1+fn+BgoODg4GAf35+fn5+fn9/f3+AgYGBgYCAf39/f39/fn5+fn9/gIGBgIB/gICBgYB/
fn5+fn5/gICBgYCAgICAgICAf35+f39/f39/gICAgYGBgIB/fn5+fn+AgICAgICAgYGBgYB/fn1+f3+A
gICAgYGAgIB/f35+fn9/gIGBgIB/f3+AgICAf39/f39/f39/f4CAgICBgYCAf35+fn9/gICAgICAgH9/
f39/f39/gICAgIB/f39/gICAgYCAf39/f39/f39/f3+AgICAgIB/f35/f39/gICBgYGAgH9/f39+fn9/
gICBgYGBgYB/fn5+fn5/f4CBgYGBgH9+fn9/f39/f4CAgYGAgICAgH9/f35+f3+AgICBgYGAf39/gICA
f35+fn9/f39/gICAgYGBgYGBf359fX1+f3+AgICBgYGBgYCAf39+fn5/f39/fn+AgICBgYGBgH9/f39/
f39/f39/gICBgYGAf35+f4CAgICAf39/f4B/f39/f3+AgIGBgYB/fn5/f39/f3+AgICAgIGAgIB/f39/
gIB/f35+f3+AgICAgICAgICAgIB/fn19fn+AgYGCgYGBgH9/f35+fn5/f4CAgYGBgH9/f4CAf39/f3+A
f3+AgICAgICAgICAf39+fn5+f3+AgICAgICAgYCAf39+fn5/gICAgICAf39/f4CAgICAgIB/f39/f39/
f3+AgICBgYCAgH9/f39/f39/f39/gICAgIB/f3+AgICAf39/f39/f4CAgICAgH9/f3+AgICAgICAf39/
f39/gICAgIB/f39/f4CAgYCAf39/f4CAgICAgIB/f39/f3+AgICAgICAgH9/f35/f3+AgICAgICAgICA
f35+fn5/gICAgIGBgYGAf39/fn5+f3+AgIGBgICAgICAf39/f35+f3+AgICAgIB/f3+AgICAf39/gICA
gIB/f39+fn5/gICAgICAgYGBgH9/fn19fX5+f4CBgYGCgYGAgH9+fn5+fn+AgICAgIGBgYGAgH9+fn5/
f4CAgICAgH9/gICAf39/f39/f4CAgICAgIB/f39/f35+f4CAgYGAgICAgH9/f39/f39/f4CAgYGBgICA
gIB/fn5+fn9/gICAgICAgICAgH9/f35+fn5/gIGBgYGAf39/f39/f4CAgICAgH9/f39/f3+AgICAgH9/
gICAgICAgH9/f39/f39/f39/gICBgYCAgICAf39/f39/f3+AgICAgYGAgICAf39+fn5/f3+AgIGBgICA
gICAf39/f39/f3+AgIGBgIB/f39/f3+AgH9/gICAgIB/f39/f39/gICAgICAgICAgH9/f39/f3+AgICA
gICAgH9/gICAf39/gIB/f39/f39/gICAgIB/f39/f39/f39/f4CAgIGAgH9/f39/f39/gICAgICAgIB/
f35+fn9/gICAgICAgIB/f39/f39/f3+AgICAf39/f3+AgICAgIB/f3+AgH9/f39/gICAgH9/f4CAgICB
gIB/fn5/f4B/f39/f4CAgICAf39/f39/gICAgIB/f39/gICAf39/gICBgYCAgH9/f39/f39/f4CAgICB
gYCAf39/f39/f39/f39/gIGBgYGAgICAf39/f35+fn5/gICBgYGBgYCAgH9/fn19fX5/gIGCgoKBgYGA
f35+fX19fn+AgYKCgYGAgICAf39+fn5+f3+AgYGBgICAgICAgH9/f39/f3+AgICAgICAgICAgH9/f39/
gICAgIB/f39/f3+AgIB/f3+AgICAgIB/f39+fn9/f4CAgICAgYGAgH9/fn5/f39/f3+AgIGBgYCAgH9/
fn5+f3+AgICAgICAgICAgH9/f39/f3+AgICAgICAgICAgH9/f39/f39/f39/gICAgICAf39/f39/f39/
f4CAgIGBgIB/f35+fn9/gICAgICAgH9/f39/f39/f3+AgH9/gICAf39/f4CAgICAgH9/f39/f39/f4CA
gICAgIB/f39/f4CAgIB/f39/f39/f3+AgICAgIB/f39/f39/f4CAgICAgICAgH9/f39+fn9/gICAgICA
gICAgICAgH9+fn5/f39/f4CBgYGBgYCAf35+fn5/f39/f4CBgYGBgYCAf39+fn5+f39/gICBgYGBgIB/
f35+f39/f3+AgICAgICAf39/f39/gICAgICAgH9/f4CAgH9/f4CAgIB/f39/gICAgIB/f39/f39/f4CA
gICAgICAf39/f39/f4CAgICAf39/f39/gICAgICAgICAgH9/f39/f39/f4CAgICAgICAgIB/fn5+f39/
f3+AgIGBgYCAgH9/fn5+fn5/f4CAgIGBgYCAgH9/fn5+f39/gICAgICAgICAgICAgICAf39/f39/f3+A
gIGBgYCAf39/fn5+f3+AgICAgICAgH9/f39/f39/f4CAgICAf39/f4CAgICAgICAgH9/f39/gICAgIB/
f39/gICAgH9/f39/f3+AgICAgICAgICAgIB/f39/f3+AgICAgICAgH9/fn5+fn9/gICAgICAgICAgH9/
f35+f3+AgICAgICAf39/f39/f39/gICAgICAf39/f39/f4CAgICAgIB/f39/f3+AgICAgIB/f39/gICA
gICAgICAf39/f39/gICAgICAgH9/f39/f39/f39/gICAgICAgH9/f39/gICAf4CAgICAgICAgH9/f39/
f3+AgICAgICAgIB/f39/fn9/f3+AgICBgYGAgIB/f39+fn5+f3+AgIGAgICAgIB/f39/f39/f3+AgICA
gICAgICAgICAgH9/fn5+fn+AgICBgYGAgIB/f39/f39/f39/f4CAgICAgICAgH9/f39/f39/f3+AgICA
gICAgH9/gICAgICAgIB/f39/f39/gICAgICAgICAf39/fn5+f39/gICAgYGAgH9/f35+f39/gICAgICA
gH9/f39/f39/gICAgICAgICAf39/f39/f39/f3+AgICAgICAgH9/f39/f39/f4CAgIGBgIB/f39/f39/
f3+AgICAgIB/f39/f39/f4CAgH9/gICAgICAgICAgICAf39/f3+AgICAgICAgIB/f39/f39/f4CAgICA
gIB/f39/f4CAgIB/f39/f39/f3+AgICAgICAgICAf39/f39/f3+AgICAgICAgIB/f39/f39/f39/f39/
gICAgICAgH9/f39/f39/f39/f3+AgICAgICAf39/f39/f39/f3+AgICAgICAgICAf4CAgH9/f3+AgIB/
f39/f3+AgICAf4B/gIB/f39/f39/f3+AgICAgICAgICAgH9/f39/f3+AgICAgICAgH9/f39/f39/f4CA
gICAgICAgICAf39/f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgIB/f39/f3+AgICAgICAf39/
f39/f3+AgICAgICAgH9/f39/f39/gICAgICAgIB/f3+AgIB/f39/f39/f39/gICAgICAgIB/f39/f39/
f3+AgICAgICAgIB/f39/f39/f39/gICAgICAgIB/f39/f39/f39/f3+AgICAgH9/f39/f39/f3+AgICA
gH9/f39/gICAgICAf39/gICAgH9/f39/f4CAgICAgICAf39/f39/f4CAgICAgIB/f3+AgICAgICAgICA
gH9/f39/f3+AgICAgICAgH9/f39/f3+AgICAf39/f4CAgICAf39/f39/gICAgH9/f3+AgICAgICAgICA
f39/f39/gIB/f39/gICAgICAgIB/f39/f39/f4CAgICAgICAgICAf39/f39/f3+AgICAgICAgIB/f39/
f39/f39/gICAgICAgICAf39/f39/f39/gICAgICAgICAgICAf39/f39/f3+AgICAgICAgICAgICAf39/
fn9/gICAgICAgICAf39/f39/f39/gICAgICAgICAgIB/f39/f39/f3+AgICAgICAgH9/f39/f39/f4CA
gICAgH+Af39/f39/gICAgICAgIB/f3+AgICAgIB/f39/f39/gICAgICAgICAf39/f39/f39/gICAgICA
gIB/f39/f39/f4CAgICAgICAf39/f39/gICAgICAgH9/f39/f39/f4CAgICAgH9/f39/f39/gICAgICA
gICAf39/f39/f4CAf39/gICAgICAgH9/f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgICAgIB/
f39/f39/f3+AgICAgICAgH9/f39/f39/f3+AgICAgICAgH9/f39/f39/f4CAgICAgICAf39/f39/f3+A
gIB/f39/f4CAgICAgIB/f39/f39/f4CAgICAgH9/f4CAgICAgH9/f39/f4CAgICAgICAgH9/f39/f39/
gICAgICAf39/f39/f4CAgICAgICAgH9/f39/f3+AgICAgICAgIB/f39/f39/f3+AgICAgICAgH9/f39/
gICAgICAgH9/f3+AgICAgICAgH9/f39/f39/gICAgICAgICAgH9/f39/f39/gICAgICAgICAgICAf39/
f39/f39/gICAgICAgH9/f39/f39/f39/f39/f39/f4CAgICAgICAf39/f39/f3+AgICAgICAgIB/f39/
f3+AgICAgH9/f39/f3+AgICAgICAgH9/f39/f39/f3+AgICAgICAf39/f39/f39/gICAgICAgH9/f39/
f3+AgICAgICAgICAf39/gICAgICAf39/f39/f3+AgIB/f39/f39/f39/gICAgICAgH9/f39/f3+AgICA
gICAgIB/f39/f39/f4CAgICAgICAgH9/f39/f3+AgICAgICAgICAgIB/f39/f39/f39/gICAgICAgIB/
f39/f39/f39/gICAgICAgH9/f39/f39/gICAf4B/f39/f4CAgICAgH9/f39/f39/f3+AgICAgICAf39/
f39/f39/f3+AgICAgICAf3+AgICAf39/f39/f4CAgICAgICAgIB/f39/f39/f4CAgICAgICAgH9/f39/
f39/f3+AgICAgICAgIB/f39/f39/f39/f39/f4CAgICAgICAgIB/f39/f39/f4CAgICAgICAf39/f39/
f3+AgICAgICAgIB/f39/f4CAgICAgH9/f39/f4CAgICAgICAf39/f39/f3+AgICAgICAgH9/f39/f39/
f4CAgICAgICAf39/f39/f39/gICAgICAgH9/f39/f39/gICAgICAgIB/f39/f39/f39/gICAgICAgH9/
f39/f39/gICAgICAgIB/f39/f3+AgIB/f39/gICAgICAgICAgH9/f39/f39/gICAgICAgIB/f39/f39/
f4CAgICAgIB/f39/f39/f39/f4CAgICAgICAgH9/f39/f3+AgICAgH9/f4CAgH9/f39/f4CAgICAf39/
f4CAgICAgH9/f39/f39/f39/gICAgICAf39/f39/f4CAgH9/gICAgH9/f39/gICAgIB/f39/f39/gICA
f3+AgICAgICAf39/f39/f39/f4CAgICAgIB/f39/f39/f39/gICAgICAgIB/f3+AgH9/f39/f4CAgICA
gH9/f39/f4CAgIB/f4B/f39/f39/f4CAgICAgICAf39/f39/f3+AgICAgICAgIB/f39/f39/f4CAgICA
f4CAgIB/f39/f39/f4CAgICAgICAgICAf39/f39/f4CAgICAgICAgIB/f39/f39/f4CAgICAgICAgH9/
f39/f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAf39/f39/f39/gICAgICAf39/f39/gICAgICA
gH9/gICAgIB/f39/gICAf39/gICAgICAgIB/f4CAgH9/f39/f4CAgICAgH9/f39/f39/f3+AgIB/f39/
f3+AgICAgICAf39/f3+AgICAf4CAgICAgH9/f39/f39/f39/gICAgIB/f39/f4CAgICAgH9/f39/f4CA
gICAgICAgIB/f39/gICAgICAgICAgIB/f39/f4CAgICAgH9/f39/f39/f4CAgICAgIB/f39/f39/f3+A
f39/gICAgIB/f39/f4CAgICAgICAgH9/f39/f4CAgICAgH+AgICAgICAgIB/f39/f39/f39/gICAgICA
f39/f39/f3+AgICAgIB/f39/f39/f3+AgICAgICAgH9/f39/f39/f4CAgICAgICAgIB/f39/gICAgIB/
f3+AgIB/f39/f39/f39/f4CAgIB/f39/f3+Af39/f3+AgICAgICAgICAgH9/f3+AgH+AgICAgH9/f39/
gICAgICAgICAgH9/f39/f39/f39/f4CAgICAf39/f4B/f39/f39/f3+AgICAgICAgICAgH9/f39/f3+A
gICAgICAgICAgIB/f39/f39/f4CAgICAgIB/f39/f39/f4CAgH+AgICAgIB/f4CAf39/gH+Af39/f3+A
gICAf3+AgICAgH9/f39/f39/f39/gICAgICAgICAf39/f39/f39/f4CAgICAgIB/f39/f3+AgH9/f4CA
gIB/f39/gICAgICAf39/f39/f39/f4CAgICAf4CAgICAf4CAgH9/f39/f4CAgICAgICAgICAgH9/f39/
f39/gICAgICAgH9/f39/f39/gIB/f3+AgICAf3+AgICAgICAgH9/f39/f4CAgICAgH9/f3+AgIB/f4CA
gICAgH9/f4B/f39/f39/f3+AgICAgICAgH9/f39/f39/gICAgICAgH9/f39/gIB/gICAgIB/f4CAgH9/
f3+AgICAgH9/f39/f39/gH9/f3+AgICAgICAgICAf39/f39/gICAgIB/f39/f39/f39/gICAgICAgH9/
f39/f4CAgICAgIB/f39/f39/gICAgICAgH9/f39/f39/f4CAgICAgICAgH9/f39/f4CAgICAgICAgIB/
f39/gICAgICAgH9/f39/gICAgICAf39/f39/f39/f4B/f39/f39/f39/f39/f39/f4CAgH9/f39/f39/
f39/gICAgICAgICAf39/f3+AgICAgICAgICAgICAgIB/f4CAgICAf39/f39/gICAgICAgICAgH+AgH9/
f39/f4CAgICAgICAgICAf39/f39/f39/f4CAgICAgICAf39/f39/f39/f3+AgICAgICAgICAgIB/f39/
f3+AgICAgICAgIB/f3+Af39/f39/f4CAf39/gICAgICAgH9/f39/f39/f3+AgICAgICAgH9/f3+AgH9/
f39/f4CAgICAf3+AgICAgH9/f39/f39/f3+AgICAgIB/f39/f4CAgICAf39/gICAgIB/f39/f39/f39/
f39/f4CAgICAf39/f39/f39/f4CAgICAgH9/gICAgIB/f3+AgICAf39/f4B/f3+AgICAgICAgIB/f39/
f39/gICAgIB/f39/f39/f39/f4CAgICAgIB/f39/f39/f4CAgICAgH+AgICAgICAgH9/f39/gICAf3+A
gICAf39/f3+AgICAf39/f4CAgICAf39/f4CAf39/f4CAgICAf3+AgICAgICAgH9/gICAgICAgIB/f39/
f4CAgH9/gICAgIB/f39/f4CAgIB/f4CAgICAgH9/gICAgIB/f39/f39/gICAgICAf39/f39/f39/gICA
gICAgH9/f39/f39/f3+AgICAgIB/f39/f3+AgH9/gICAgIB/f3+AgICAgH9/f39/f39/f39/gICAgICA
gH9/f39/f4CAgICAgICAgH9/f39/gICAf3+Af4CAgICAgIB/f4CAgICAgH9/f39/f39/f3+AgICAgIB/
f39/f39/f39/f3+AgH+AgICAgICAf39/f39/gICAgICAgICAgICAf39/f4CAf39/f39/gICAgICAgH9/
gIB/f39/f39/f39/gICAgICAgICAf39/f39/gICAgICAf39/gIB/f39/f3+AgICAgICAgH+Af39/f3+A
gICAgICAgIB/f39/f4CAf39/f4CAgH9/f39/f4CAgIB/f39/gICAgH9/f39/f4CAgICAgIB/f4CAgIB/
f39/f4CAgICAgICAgICAgH9/f39/gICAf39/gICAgICAf39/f39/f39/f39/f4B/f39/f39/f3+AgICA
gH9/f4CAgICAgICAgICAgIB/f39/f4CAgICAf39/f3+Af39/f3+AgICAgH+Af4CAgH9/f39/f39/gICA
gICAf4CAgIB/f39/f4CAgH9/f4CAgICAgH9/f3+Af39/f39/gICAgICAgH+AgICAf4CAf4CAf39/f39/
gICAgICAgIB/f39/f39/f39/gICAgH9/f4CAgICAf39/f39/gICAgICAgICAgH9/f39/f39/gICAgICA
f39/f39/f39/f4CAgICAgICAgICAgH9/f39/f3+AgICAgIB/f39/f4CAf39/f3+AgICAgH9/f4B/f3+A
gICAgICAgH9/f39/f3+AgH9/gICAgICAf39/f39/f3+AgICAgICAgICAf39/f4CAgH+AgICAf39/f3+A
gH9/f4CAgICAf4CAgH9/f39/gICAgICAgICAf39/f39/f39/f4CAgICAgICAgH9/f39/f4CAgICAgH9/
f4CAgICAf39/gIB/f39/gICAgICAgICAgH9/f4CAf39/f3+AgICAgICAgIB/f39/f39/f3+AgICAgICA
gICAf39/gICAf39/f4CAgIB/gICAf39/f39/f39/gICAgICAgH+AgH9/f39/gICAgH9/f4CAgIB/f4CA
f39/f3+Af39/f4CAgICAgICAgIB/f3+AgICAf39/f39/gICAgICAf4B/f4B/f39/f4CAgH9/f3+AgIB/
f39/f39/f4CAgIB/f3+AgICAf3+AgIB/f39/f39/f39/f4CAgICAgICAgH9/f39/gIB/f4CAgIB/f3+A
gICAf3+AgICAf39/f4CAgH9/f4CAf39/gICAgH9/f3+Af39/f3+AgICAf39/f4CAf39/f3+AgICAgICA
f39/f3+Af39/gICAgH9/f4B/f39/f3+AgIB/f3+AgICAgH9/gICAf39/f3+AgICAgICAgH9/f3+Af39/
f39/gICAf39/gIB/f3+AgIB/f39/f4CAgH9/gICAgIB/f4CAgH9/f39/f39/f39/gICAgICAgICAgH9/
f39/f39/f4CAgICAgICAgICAf39/f39/f3+AgICAgIB/gICAgH9/f39/f3+AgICAgICAgH9/f39/f39/
gICAgH9/gICAgH9/f39/gH9/f39/f3+AgICAgICAf4CAf39/gH9/f4B/gICAgICAgICAgH9/f39/f39/
gICAgIB/f39/gICAgH9/f39/f39/f3+AgICAgICAgIB/f39/f3+Af39/gICAf3+AgICAf39/gIB/f39/
f4CAgICAgIB/f39/f39/gICAgICAgICAf39/f39/f39/f3+AgICAgICAf39/f3+Af3+AgICAgICAgIB/
f39/f4CAgH9/f3+AgICAf39/f3+AgIB/f4B/f3+AgH9/gIB/gICAf39/gICAgH9/f4CAgH9/f3+AgIB/
f39/gICAf4B/f3+AgICAgICAf3+AgICAf39/gICAgIB/gICAf39/f39/gICAgH+AgICAf39/f3+Af3+A
f39/gIB/gICAf3+Af39/f39/f4B/gICAgICAgH+AgH9/f39/gH9/gICAgICAgICAf39/f39/f3+AgICA
gICAgICAf39/f39/f39/gICAgICAgH+AgH9/f39/f4B/f4CAgIB/gICAgIB/f39/f3+AgH9/gICAgIB/
f3+Af39/f3+AgICAf4CAgICAgH9/gICAf39/f4CAgH9/gIB/f39/f3+AgH9/f3+AgH9/f3+AgICAgICA
gICAf39/gICAf39/f4CAf39/gICAgIB/f3+Af39/f39/gICAgICAgIB/f39/f4CAf39/gICAgH+AgH+A
gH9/f39/gH9/gICAgICAf39/f39/f3+AgICAgICAgICAgH9/f4CAf39/f4CAgH9/f3+AgICAf3+AgIB/
f39/gICAgH+AgICAf39/gIB/f39/f4CAgIB/f39/f3+Af4CAgH9/f3+AgIB/f4CAgICAgH9/gH9/f39/
gICAf3+AgIB/f39/f4CAgIB/f4CAgICAgH+AgH9/f39/gICAf39/f4CAgH9/f4CAgH9/gIB/gIB/f4CA
gICAf39/gICAgH9/gIB/f4B/f39/f3+AgICAgH9/f4CAgIB/f39/gICAgH9/f39/f4CAgICAgH+AgH9/
f39/f3+AgIB/f4CAf4CAgH9/f39/f3+AgH9/f4CAgICAgH+Af3+AgH9/f39/f4CAgH9/gH+AgICAf39/
f39/gICAgICAgIB/f4CAf4CAf3+AgH+AgICAgICAf3+AgH9/f4CAgICAf39/gH+AgH9/f39/f3+AgICA
gIB/f4B/f4CAf39/f4CAgH9/f4CAgH+AgH9/f39/f4CAgICAgICAgICAf4CAf3+AgH+AgIB/gH9/gICA
gH9/f4CAf3+Af3+Af39/f4CAgH9/f39/gICAgH9/f4CAf3+AgH9/gICAgICAgICAf4CAgICAgH9/f4CA
f4CAgICAgH9/f39/f3+Af3+AgICAgIB/f4B/f39/f39/f3+AgICAgICAgIB/gICAf39/f4CAgIB/f39/
f3+AgH9/gICAgICAf39/f39/f4CAgH+AgH9/gH9/f4B/gICAgICAgICAf4CAf3+Af39/gICAgIB/f39/
f3+AgIB/gICAgICAgICAf39/f4CAf39/f39/gICAf3+AgICAgH9/f39/gICAgH9/gICAgH+AgIB/f39/
f4CAgIB/f4CAgIB/f3+AgICAf39/gICAgH9/gICAf39/gICAgICAgICAgICAgH+AgH9/f39/f4CAgICA
gICAf4CAgH9/f35+f39/f4CAgYGBgYGAf39/gH99eXh6f4OEg4ODhYaFgn98enp7fH5+fX6AgoODgoB/
f4CAgIB/f35/gIB+fXx9foCBgYCBgYKCgoF/fn1+f39/fn5/gIGBgYB/f4CAgYGAgH9/gIB/fn5+fn+A
gICAgIGBgYGAf35+f39/f39/f4CAgIB/f3+AgICAf3+Af39/f39/f39/gICAgICAgICAgH9/f4CAf39/
f3+AgICBgYGBgH59fX19fn9/gICBgYGCgYGCg4ODgHZsbnmDiIqGhIWHhYOCgX59gIB9d3JzeX+Cg4OD
hIWGh4WDgH59f4KCeGdhbXyHi4iFi5SXkomAdW5udHh7eHV6hImKiYR/foCChIWEf3x+gYB8dXByeH6E
h4aEhYeIh4WBfXp7e3p5d3d6foGEhYWFhoaGhYJ+e3p8fHt7ent9gIKDg4KCg4SEg4F/fX19fHt7e3x+
gIKCg4SEg4OCgH99fX19fX1+f39+fYCCg4KAf4CBgYGBgX99foCBgoJ/dmtrdoKJi4qMkZOOhXtybG11
foKCfnp8gYOEhoeGhIKBf3x6eXx/gYOGhnxnW2Z6houMj5qkopSEdmhfX2ZvdXuCjpeYk4uDfX6AgYB6
cGdpdIGKjYqIiIqMkI98XEpYcoOMioaPn6Wdj35rYGNvfIN+eHqAgoaJiYmJiYmHgnlxcHZ/hYeDd2Zg
cYSLh4KHmKajkYBzaGRpcHR1c3mJlJKKhIKFiomHhH51b3J5gYiGdmRic4eRj4SDkqCej39wZWRrc3V0
cnqNmpmSjIaDgoB7d3JucHmCg3x2eIOQmJeOgnt6fntuYWBpeYuUk5COjY6Oh3hraG95gIKAf4GFiIqF
fHZ1e4SKh4B7enyChoR/f4KFiIZ5ZFpkdYOLjo+Wn6GXh3ZnX2Focnp9gY2XmJCEenh+g4SAd25sc3+K
jYmHiIyRkoRgQUdjfY+UkputsaORfmVSUmBwfH98gYmNjpCQkIyFgoJ7bmZncH2JkJSIaFRng4yKhIWa
sKyTfm1cV2BtdHR3hJackoWCi5eViHtyamZqcnuIlY5vVGB9jZGKhJWxt5+Cb11TWGFmaWx5lamklI6T
nJuMempfW2FvgYdyU1d+nqeilZOhq6CKclVCR1xveXl6i6SwqJaDeX2IjYZzXVRdc4ualnhcZIafopB3
dI2gm4dwWlFfdoWIgHuGnKach3RoanWAhoJ6dXZ+ho2QkpCEbFtic3p6fYOQnqKYinxvaWtwdHd9h5KW
kIZ+d3FsbXmJkYyDfHyBiY6Oi4V+c2FQVmdyfIydsLu0nIV1Z11bXWFreIeUlouCho6RkIuEf3pxaWhw
fY2akW1OVXWMkouGl7O5o4ZsVUhQZXR3dHuSp6aYioWMkIh8cGZeYGx/k6CVb09Ye5KWjoaUsruif2VR
SFBfanB3hp2sp5aMkpyZh3FgVldjdImOa0NViau1qpeasLCVeV9AMkFZbXl7g524vrCdkpCMfWlYTUxc
d4h/Y1t2mK+0qaGnq5qBalA5N0VZbHyHmK+7uaydk4yAbV1TT1JjfY19XmGDorOxoZqlp5J6Z0w4PFFm
d4ONnbCzpZaPjo2GdGRbUU9jg5yegl5fhKKnmoWEmqeZgGdMPkxoeoOGiZaqrpyHfHt/gH52aFxdboad
pY5gTmyNmZmLf46lp5J2WkdHW3eOlIuLnKabhG5haYCTlYdwX2BxjKWtnXdORmiJinhse6XGv5p3YVVa
bXh0a2yBm6GRfXqIl5iPg3ZoY2t8j5iBUzxahZqgmZKftbacfF5FP1BmdHh3gJmsqZqRkpaQgW9fVFZk
epSadkhPgKSto5GYsLKXfWRFNT9VaXmFkaS1s6CSlJiOemZXTVJpg4ltSlR/pLq6qKWyrZB4YkEqMEdh
doKPqMHIuqOVkIVxXU9GSV96g21Za4+tv7qqqrChf2VUPzA2S2Bziqa+ycOwnZOJe2dTQ0JTbYWHa1Zt
mLXAuKinq5x8Y0suJz9ccIOSn7PCv6+dkIZ5aVhIQEdggqKqiWNnjKivoIiHmZ6PdlpAO0pedYiNkKS9
vaaRhoF9c2JTTVFigJ2igVhdiKu1po+OnqCKcFY9NEZkfI6Yn623rJSAeXh7enRpWExYfKS5qHNKXYqi
oYx3fZinmX5gRkJYdIaOjo+ao56NgH18e3t3bWRjcISbqI9aRWaJmqKXi5SjoI53WUBBV3KIkYqKmqSd
k4+Mhn5zZl1aYnaSpJNgQ12KoqaclaKxqIxyVzswP1t2ipilsbKll5WXj3phUEpQZIKRf1lRd6C5vaic
qK2TdmVKKiI4W4Gfqauxtq+lpJqAYkg9Rlt2hnNLToCuxsewpLG4m3NUMRcePGOFmZ+sv8S7sKSPdWBR
S1BaWT80X5S0x87Hycu1imNCIxYkPFx/k52zzM7Cu6uJaFJHSlhgTjA4bJ+9y8jEyce0k2k7FgwjSGN2
jKS/0tPGtZ+EaVRIR09TRDVOgae8xsbIy76deFk+LS47Slxtfpq6ztLMvqKCZ1RHP0JSZ3d0ZnGTsby0
paezqottUzsxOUtdbX6TsczRv6aWinpoVklDSFx7jHtkcZSuu7Wkoqeae2VXQDI8VGp/j5qqvcO4ppaG
c2FTS0hPZICQgmtyj6i1sKCbn5d/aFVAOUdcbH6Pm6u8u6qZj4R5bVtMR1BjfZqmkWtlhKCpoY+MmJuK
cVpIQEthdYWQnK65rpSCg4mFdGBRTVZsiqapfk1UhaeqnIqSqquPc11DND5Xc4udqK2toI2JlZiHbFVK
TV11kp19TFGHscCyko6mqo1wWTokMFV7mqmlo6ionZeZj3pjTUdTaoWLaEJVjLTHwaehr6uLaE0vHSpS
e5afnqe2urGkloNvXlFKT2R6bU1TgKa9x7ituLeVa1M6IiM9Y4WXmaO4wbuzp49zX1BMU2BnWD9NgKm/
x7yyvcWpe1UxFx89WHOKkp++0cWzqph8Y1BGS1lgTzpRhq3Ax8K8vbicd1c6Jio/Vmh5hpy7z829q5iE
cl9LPTtMaIKHcGN/qL69raOoq5dzUjwwMkJYcYeatMrLtZyPjYd4YUo8PFJ0kZZ4X3afucKwlZWgk3Zh
SjQySWZ7iZGet8W6opCGgn1sUkRETWKCpLOdcWKAnqCUg3+Uo5Z6YU1BSWF3hY6Yq7itkH2AjIl1YldT
V2Z7kKmuh1pki5iShnqHo6eNdmNMRFdwgYyPkaCrn4h8gISAeG1gWmFygpWoqodZV3aGiIeAiaiym39q
VUlTaXyGipGdoZN+e4uVi3ptY2FncHqJnqqVZk1heoaMiIynuquKbVZIS1dlfJSgoJmKfYKVopiDblxW
YnJ9jp6FVExzlJ6Yio+vwqmBY0c0PVhvg5OZm56ZkJKeoI93YVVTXGx/kJFxUmeQp6qbkJ2tpottUToz
QWOIm5uUlJ6hnJyeknthUFBaaHuMhGJVeJ6vsJ2Pn7KhfGRQOjZJZX6Ql5qlrqidnJyPdlpGR1tygHZa
U3egu8Ovm6Com3xiSzc0RV51hpKitLesoZ2Zj35jTEJGVm6HmIhmaJCts6qWj5ygiW5aRDdFX29+k6Gs
t7CYh4uSindeSkhTZXqTpZpyX3ydpJqGgJKimX5pVkVFW3iJioqdtbKXfXmHj4BqX1xeaHR9jJ+rpIRi
W2l6g4GAkqqslX1sW1BXaHuIkJeblIh+f4yRiHxvamxubnKBk5+fiWVXan2ChIOLoq+fhHFgU1dlcXyJ
lqKqoIp4cm9vdHx/fHJvdoGNkpWZnZd/W0hUZGd0h5WmtK+biXlnX2FnbniDjY6Hf32Bio6Jh4aAd3Jx
cXaCjJKWjGtRW3F9goSKoLKsloJxYVpeZ3J9hY2VkoeBg4uNhHt4d3R0dXZ6g42XoZx4S0JZbXyMlKC3
vaiOe2NNR1Nqf4mMjIiCgo2eppuHd21paWloboGTmY1vV2B5ipOWm6qzpYdtWklAS2iIm56WjIWEi5uj
loFvY2FnaWlvg5qjlHFea32Fi46VpaybfWZZUlVic4SPkY6Lh4mUoaWXfmdbWmBqdoaRg2NhgpyhmIyS
paeRdlxFQVt4gIOHiJCdm42KlJiQf2pZVVxqeoiXm4Nla4aPioiKmKuqjG1dUU1ZbHuKlZialod+iZma
i3ZjXWBpdH6KkIFna4iVj4mGkqaokntpVElVZ3F8iZakqpyEe4eNhHlwa2dnbXR8h5ajo4xmU2N6hIKC
jqOrnId1ZFhZY297iZWaloyAfImVj35ya2docHh+hI6XnJ2MZU5ccXuCiZGepZ6NfWxbV19tfomOl6Kh
koN5c25rbnd7dHN7hY+ampCJiYqJe1k8Ql53i5ebqbi1o453X1FSXWt3fIGNlJWSi4eHh4eGf29laHB6
goSDho+YlYBiV2V3hYyLjJedlId+cWBbZneGjIuNlZaPhXtycHZ+gHtvaXKDkZaSjIqIgoGJjHhROUxy
ipOSkqC0uKaMbVNKWWx1dXN6jJmYk4+OioeFfXFpanBydnyBhpCdo5NtT1Rqe4eLi5emppeFcVxRWm6D
kZKNiYR/gImRjoN1a2txeH2Ag4WIiouQl45oQkZlfpCZk5ioqpaDdF9QXXyPi3ttcIGNjZCWlYyDenFt
cHV5f4SGiIBqW2Z6jJmbmaKolHJhYGJqd39/fHp/ipCPjY+Pi4F1bG1xcnF3g5KdmXpXV3CCjZKPlqOf
hnBoZGZzf315fIKKjoiBh5KVjoJyZmVvd3uCiYuDcm15goaJi5CanpF7bGVgXWR2iZSVk46GgYKKj4h6
bmhqcnZ1eomVmZmXhWdXYW95gIOMnaOYjIN2ZV9mcn6Jj4+Kgn19hoyHfnh3dnZ5fH2BiY2MjY+EaVJW
anuIkJKbpKOVhHVkWFppeICEipGTj4uKiod+dXFwbm1xeIOOko+LiIWHjo12UkVbeYmMiY+fqaSWhHBe
WWJ0gH97gY+VkIaBgYKDg352bWxxeYOJiYiJiYiLkIx2VkldeIaJhYmcrKqbh3JfWmVzenl3fo6Yk4Z+
foOKjYl9bmVmb3uEiIqLjIuHhomKhXhfUF1zf4OGiZiqr6OSfGVbYGhqam14jJuclpGQjomFfnFjXWBo
c4CKkZmblI6NjYqEclNATWl+iImOoLO1ppJ6Z15ham9raHB+jJOUlJmbk4d9dGtkZWpxeH+Fi5CQjpKW
lo1yUUdZbnuFiZCir6iXhnNiXmh0e3t5eoCIjY2RlJGIfXRua2xvdHyChYiOk5aalXlVUWZ2fX58h5qi
mo+GeG1ygYeAc2hpeIGBhZGVj4iDfnl5e3t6eXZ0d4CJkZWLcF5sgoqHf3yJmZmJfHNscX+FgHl1eYOG
gX+GjIqEfnt7fn9+eXd4e4CHj49/aWJxgIiKiIqUmpKBdGxmZm9+iouHh4qIgn6EiYV7cG1xeHx+g4qM
iYeHh4iJgWxXWGx/ioqFjZ6lnIx8bWRmb3d5eX6GjIuJiIuMhn12c3NzdHd9g4aHiYuIgoOIin9pWFxw
f4SGiJOjqJuKfG5kY2txcnJ3hZKVkYyKjY+LgXlwaGVna3J8hI2Xm5eRjYiBenVxbmtjXWR2hpCZnqKm
opaFdWVbWmBmbnaAjZmbmJWSjoqGfnNqZGNla3R9hpCVlpORj4uCe3ZzcXFzc21mbH6MlJaVmJ6ckYR2
Z15eY2pyeoCLmZ6ZkImEg4F9d3BrbnN3en6EiIyNiYSChISCf3p2d3l7f4OBdmpugIyNiYWLmJqPgnZr
ZmhscHN3f4+dnZSMhoF9eXR0dnZzcnZ8goiMjo2JhIOBe3V1d3h6fH1+goqQjn9wbnmDhoJ8fomPjIV9
dnFzen5+fH6Fjo+Hf3x8fX6AgH98eHZ4fYCDhoqMh4B6eXl4eX2Af319f4GEh4eGhYN/dm1tdn2BhYeL
kZONhH53cnFzdnh6fYSMjYiEhIWFhIB7eHd1cnN5gYaJioqJhoKAfXp5eHd3eXp9gIWKjIqIhYJ/eXBr
bnh/hIeIio+QjIZ+d3NzdXh6fH6ChIWFh4eHhoSAfHh1dXd5foKEg4SEg4KBgH9+fn59fXx9foCEhoWD
gXt0dHyBgYGAhIuNiYN+e3l5eHd5fH6Bh4iFgoKCgoGAf39/fXl2eHyBg4SGhYSEgoB9ent9fX18e3t9
gYOFhoeGhIJ/fHp6enl3d3qAhoiIhoiKiYV/enZ2eHh3eX6Bg4eKiYaDgoB+fHp5eXl7fX6BhIWEhYSD
gX9+fXp4eXx+fn6Ag4SFhYODg4KAfnx7e3t6d3h+hIaHhoaHiIWAfXp3dnh5ent+goeLiYWEg4B9enh5
e35+fn5/gYKDg4SEhIKAfXp5eXp8fn+AgoSFhYSEg4F/f318eXl6fH1+f4CDhoeFhIOBf358e3p7e3x9
fn+Bg4SDg4OEhYOAfXt6e3x8e32AgoODg4KCgoKCgH59fHx9fn18fYCCgoOCgoKDgn99fHt7fH1+gIGD
g4KBgICAgYB/f3+Af35+fX5/gIGCgoB9fn+BgoKBgIKDgX17ent9f4CAgYOEhIKBgH59fX18fH1+gIGC
goKCgoGAgICAf359fH19fX5/gIKDg4OCgoGBgX9+fXx7fH19fn+BgoOFhYSCgX99fHx8fH19f4CAgIGC
g4ODg4KAfn18fHt8fX+BgoKCgoKBgYB/f359fn59fX5/gIGBgYGBgYGAf39/f39/fn5+f3+AgICAgYGB
gYB/fn1+fn5+f4GBgoKBgH9/fn5/f3+AgICAgYGBgICAgH9/fnx9foCBgYGBgYGAf35+f39+fn9/fn6A
gYKDgoKBgH9/fX18fX1+f4CCg4SEg4KAf318enp8fX+BgoKCgoKBgH9+fX19fn5/gICAgICBgH9/gICA
gIB/fn9/f39/gIGBgICAf39/fn5/f3+AgIGBgICAgH9+fn5+f4CAgYGBgYGAf39/f39/f4CAgIB/f39/
gICAf39/f39/f4CBgYGAgIB/fX1+f39/gIGBgYGBgYGAgIB/fX19fX5/gICBgoOCgYB/fn5/f359fX6A
gICAgYKDgoGAf35+fn5+fn1+f4CBgYKCg4KBgH99fHx8fX1+gIGDg4OCgoB/fn18fH1+f4CAgICBgYGB
gYCAgIGAf319fX19fn5/gIGDhISDgoF/fn18e3t8fX5/gYKDhISEg4GAf359e3t7fH1/gIKCgoODgoGA
f35+fn59fHx9fn+AgYODg4ODgYB+fXx7fH19fX+AgoODg4OCgYB/fn18fHx9fn+AgYKDgoKDg4KAfn18
fHx8fX+AgYKCg4KCgYB/f39+fn5+fn9/gICAgYGBgICAgICAf39+fn5+fn5/gIGBgYKCgoF/fn19fX5+
fn9/gIGBgoKCgYCAgH9+fX19fn5/f4CBgoKDgoKBgH9+fXx8fH1+gIGCg4OEg4KAfn19fX19fn9/gIGB
gYGBgYGBgIB/fn59fn1+fn+AgIGBgYGBgYB/fn5+fX1+fn+AgoKBgYCAf39+fn5/gICAgICAgYGAgH9/
fn5+fn9/gICAgICAgICAgICAgH9/fn19fX5/gIGBgoKBgYGAgH9+fX19fn5/gIGBgYKCgYB/f39/f39+
fn5/gICAgICAgICAgICAgICAgH9+fn5+f3+AgIGBgYCAgH9/fn5+f39/f39/gIGBgICAgICAgH9/fn5/
f39/gIGBgYGAf39/f3+AgICAgH9/f35/f4CAgYGBgH9/fn9/f39/f4CAgIB/f4CAgH9/gICAgICAgH9+
fn5+fn5/gYKCgoKCgYB/fn18fH19fn6AgoODgoKBgYB/fn59fn59fX5/f4GCgoKCgoGBgH9+fX19fn5+
f3+AgYKBgYGAgH9/f39/f39/gH9/f39/f4CAgH+AgIB/f3+AgIB/f4CAf39/f39/f3+AgIGBgYGBgH5+
fX1+fn5/gIGCgoGAgH9+fn5+fn9/gICAgICAgICAgH9/f39/f4CAgICAgICAf39/f3+AgICBgICAf35+
fn9/f3+AgIGBgYGAgH9/f35+fn5+f3+AgYGBgoGBgH9/fn19fX1+f4CBgoKCgoGAf359fX1+fn9/gIGB
gYGBgYCAf35+fn5+fn9/gICAgYGBgYGAgIB/fn5+fn5/f4CAgYGBgYGAgH9+fn5+fn9/gICAgIGBgYCA
f39/f39/gICAgICAf39/f39/gICAgICAf39/f39/gICAgICAgH9/fn5+f4CAgIGBgYGAgH9+fn5+f3+A
gICAgICAgH9/f4CAf39/gICAf39/f4CAgICAgICAgICAgH9/fn5+fn5/f4CAgYGBgYGBgIB/f359fX1+
fn+AgYKCgoKBgYB/fn5+fn5+f4CAgIGBgYGBgYB/f39+fn5+f39/f4CAgIGBgIB/f39/f39/f4CAgICA
gICAgH9/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgH9/f35/f3+AgICAgICAgIB/f39+fn5+f3+A
gIGBgoKBgH9+fn19fX5+f4CBgoKCgoGAf35+fX5+fn+AgIGBgYGAgIB/f39/f35/f3+AgICAgICAgIB/
f39+fn5/f3+AgICBgYCAgIB/f35+fn9/f4CAgICBgYGAgH9/f35+fn5/f4CAgYGBgYGAf39+fn5+f3+A
gICAgICAgH9/f39/f39/f3+AgICAgICAf39/f39/gICAgICAgICAgICAf39/f39/gICAgIB/f39/f39/
gICAgICAgH9/f35+fn9/gICAgICAgYGBgIB/f39+fn5+f3+AgYGBgYGBgH9+fn5+fn9/f4CAgYGAgH9/
f39/f3+AgICAgICAf39/f39/gICAgICAf39/f39/f4CAgICAgH9/f39/f39/gICAgICAgIB/f39/f39/
f39/gICAgIB/f3+AgH9/f39/f3+AgICAgIB/f39/f39/f4CAgICAgICAgH9/f39/f39/gICAgIGAgIB/
f4CAf39/f39/f3+AgICAgYGAgICAf39+fn5+fn9/gICBgYGBgIB/f39/f35+f39/gICAgICAgICAgH9/
f39+fn5/gICAgICBgYCAf39+fn9/f4CAgIGAgICAf39/f39/f39/f39/f4CAgYGBgIB/f39+fn5+f4CA
gYGBgICAf39/f39/f3+AgICAgICAgICAgICAgIB/f35+fn9/gICAgYGBgYCAf35+fn5/f3+AgIGBgYCA
gH9/f39/f39/f39/f4CAgICBgYGAf39/fn5+f39/f4CAgICAgYCAgH9/f39/f39/f3+AgICAgYCAgICA
f39/fn5+f39/f4CAgYGBgYCAgH9/f39/f39/f4CAgIGBgYCAgH9/fn5+fn9/gICBgYGBgICAf35+fn5/
f4CAgICBgYCAgH9/f39/f39/f39/f3+AgICAgICAgICAf39/f39/f39/gICAgYGBgICAgH9+fn5+f39/
gICAgYGBgICAf39/fn5+f3+AgICAgICAgICAf39/f39/f39/f4CAgICAgICAf39/f39/f39/f4CAgYCA
gICAf39/f39/f3+AgICAgICAgICAgIB/f39/f39/f39/f4CAgICAgICAf39/f39/f3+AgICAgICAf39/
f39/gICAgICAgH9/f39/f39/gICAgICAgIB/f39/f39/f4CAgICAgICAgH9/f39/f39/gICAgICAgICA
gH9/f39/f35/f4CAgIGBgYGAgH9/fn5+fn9/gICBgYGBgYCAf39+fn5+f3+AgICAgICAgIB/f39/f39/
f4CAgIB/gICAgICAf4CAgH9/f3+AgH9/f39/f39/f4CAgICAgICAgIB/f35+f39/f3+AgYGBgICAgICA
f39/f39/fn9/gIGBgYGBgIB/f35+f39/gICAgICAgH9/f39/f3+AgICAgICAgH9/f39/f3+AgICAgICA
gH9/gIB/gICAf39/f39/f39/f3+AgICAgICAf39/f39/f3+AgICAgICAgICAgH9/f39/f39/gICAgICA
gH9/f39/f39/f4CAgICAgICAgICAf39/f39/f4CAgICAgICAgIB/f39/f39/f39/gIB/gICAgICAf3+A
gICAgIB/f39/f39/f4CAgICAgIB/f39/fn5+f3+AgICBgYCAgH9/f35+f39/f4CAgYGBgICAgH9/f39+
f39/f4CAgIGBgICAgH9/f39+fn5/f3+AgIGBgYGAgH9/f35+fn9/f4CAgICAgICAgIB/f39/f39/f39/
f4CAgICAgICAgIB/f39/f39/f39/f39/gICAgICAgH9/f39/f39/f4CAgICAgICAgH9/f39/gICAgICA
gIB/f39/f4CAgICAgIB/f39/f39/f39/gICAgICAgH9/f4CAgH9/f3+AgIB/f3+AgIGAf39/f39/f39/
f4CAgICAf39/f39/f39/f4CAgICAgICAgH9/f39/f3+AgICAgICAgIB/gICAgH9/f39/f39/gICAgICA
gH9/f4CAgICAf39/f39/f3+AgICAgICAgIB/f39/f39/f39/f4CAgH9/gICAgICAf39/f39/f39/gICA
gICAgICAgH9/f39/f4CAgICAgIB/f39/f3+AgICAgICAf39/f39/f4CAf4CAgICAgICAf39/f39/f4CA
gICAgICAf39/f39/f39/f3+AgICAgICAgICAf39/f39/f39/f39/gICAgYGBgYCAf39+fn5+fn9/gIGB
gYGBgYCAgH9/fn5+fn5/f4CAgYGBgYGAgH9/f35+fn5/f3+AgIGBgYCAgH9/f39/f39/f39/f4CAgICA
gICAgIB/f39/f39/gICAgICAgICAf39/f39/f3+AgICAgICAgICAgH9/f39/f39/f39/gICAgICAgICA
f39/f39/f3+AgICAgICAgH9/f39/f3+AgICAf39/f4CAgICAgIB/f39/f39/f4CAgICAgICAgIB/f39/
f39/gICAgICAgIB/f39/f39/gICAgICAgICAf39/f39/f39/f4CAgH9/gICAgH9/f4CAf39/f3+AgICA
gICAgIB/f39/f39/f4CAgICAgICAf39/f39/f3+AgICAgICAgICAgH9/f39/f39/f4CAgICAgICAgICA
f39/f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgIB/f4CAgH9/f39/f39/gICAgICAgH9/f39/
f39/f39/gICAgICAgICAf39/f3+AgICAgICAgICAgH9/f39/f39/f4CAgICAgICAf39/f39/f39/f4CA
gICAgICAgIB/f39/f39/f3+AgICBgYGBgIB/f35+fn5/f4CAgIGBgYGAgICAf39/fn5+f39/gICAgYGB
gICAf39/f39/f39/gICAgICAgICAgH9/f39/f39/f4CAgICAgICAgH9/f39/f39/f4CAgICAgICAf39/
f39/f39/f4CAgICAgICAgH9/f39/f39/f3+AgICAgICAgH9/f39/f39/f39/gICAgICAgIB/f39/f3+A
gICAgICAgIB/f39/f39/gICAgICAgIB/f39/f39/gICAgICAgH9/f39/f39/f39/gICAgICAgIB/f39/
f39/f4CAgICAgICAgH9/f4CAgICAgIB/f39/f4CAgICAgICAgICAf39/f39/f3+AgICAgICAgH9/f39/
f39/gICAgICAgICAgICAf39/f39/f39/gICAgICAgICAgIB/f39/f39/f4CAgICAgICAf39/f39/f3+A
gIB/f4CAgH9/f39/f39/f39/gICAgICAf39/f39/f39/gICAgICAgH9/f39/f39/gICAgICAgH9/f39/
f39/gICAgICAgICAf39/f39/f39/gICAgICAgICAgICAf39/f39/f39/gICAgICAgICAgIB/f39/f39/
f3+AgICAgICAgH9/f39/f39/f3+AgH9/f4CAgICAgH9/f39/f39/gICAgICAgH9/f39/f4CAgICAgICA
f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgICAgIB/f39/f39/gICAgICAgH9/f39/f3+AgIB/
f39/f39/f3+AgICAgICAgH9/f39/f3+AgICAgICAgICAf39/f39/f39/gICAgICAgICAf39/f39/f39/
f3+AgICAgICAgH9/f39/f39/f39/gICAgICAgICAf39/f39/f3+AgICAgICAgICAgH9/f39/f39/gICA
gICAgH9/f39/f39/gICAgICAgICAgIB/f39/f39/f4CAgICAgICAf39/f39/f39/f4CAgICAgICAgH9/
f3+AgICAgH9/f39/f3+AgICAgICAgIB/f39/f3+AgICAgICAgIB/f39/gICAgH9/gIB/f39/gICAgICA
gICAgICAgIB/f39/f39/gICAgICAf39/f39/f4CAgH9/f39/f3+AgICAgICAgIB/f39/f39/gICAgICA
gICAf39/f39/f39/gICAgICAgICAgIB/f39/f39/f4CAgICAgICAf39/f39/f39/gICAgICAgICAf39/
f39/f39/gICAgICAgICAf39/f39/f3+AgICAgICAgICAf39/f39/f39/f3+AgICAgICAgIB/f39/f39/
gIB/f4CAgICAgICAgICAgH9/f39/gICAgH9/gICAgH+AgICAgICAf39/f39/f3+AgICAgICAf39/f39/
f39/f4CAgICAgICAgH9/f39/f3+AgICAgIB/f39/f4CAgICAgH9/f4B/f39/f3+AgICAgICAf3+AgICA
gICAf39/f39/gICAgICAgIB/f39/f39/f4CAgICAgICAf39/f39/f4CAgICAgICAgH9/f39/f39/gICA
gICAgICAgICAgICAf39/f39/f4CAgICAgIB/f39/f39/f3+AgICAgICAgH9/f3+AgICAgICAgH9/f39/
f39/f39/f3+AgICAgICAgICAf39/f39/f3+AgICAgICAgICAgIB/f39/f39/f4CAgICAgIB/f39/f39/
f39/f4CAgICAgIB/f39/f4B/f39/f39/f39/f3+AgICAgICAgICAf39/f39/gICAgICAgICAgH9/f39/
f39/f39/gICAgICAgIB/f39/f39/f3+AgICAgICAgH9/f39/f39/f4CAgICAgICAgIB/f39/f39/f39/
gICAgICAgICAf39/f39/f39/gICAgICAgICAgICAf39/f39/f39/f4CAgICAgICAgH9/f39/f39/f3+A
gICAgICAgICAgIB/f39/f39/f3+AgIBMSVNUxAAAAElORk9JQ1JECwAAADE5OTQtMDItMDUAAElTQkpu
AAAAUEFSVElBTDpiaXJkLCBjcm93LCBjb21tb24gY3JvdywgY2FsbHM7IFRoZSBIb2xseXdvb2QgU291
bmQgTGlicmFyeSwgQzE5OTQsIE5ldyBFZGVuIE11bHRpbWVkaWEsIDE4MDA3MzUtRURFTgBJU0ZULgAA
AFNvdW5kIEZvcmdlIDIuMDtTb25pYyBGb3VuZHJ5IFNvdW5kIEZvcmdlIDUuMAAL
</value>
</data>
</root>

View File

@ -181,14 +181,14 @@ namespace BizHawk.MultiClient
public void CreateDevice()
{
DestroyDevice();
Device = new Device(d3d, 0, DeviceType.Hardware, backingControl.Handle, CreateFlags.HardwareVertexProcessing,
new PresentParameters
var pp = new PresentParameters
{
BackBufferWidth = Math.Max(1, backingControl.ClientSize.Width),
BackBufferHeight = Math.Max(1, backingControl.ClientSize.Height),
DeviceWindowHandle = backingControl.Handle,
PresentationInterval = PresentInterval.One
});
PresentationInterval = Global.Config.DisplayVSync?PresentInterval.One:PresentInterval.Immediate
};
Device = new Device(d3d, 0, DeviceType.Hardware, backingControl.Handle, CreateFlags.HardwareVertexProcessing, pp);
Sprite = new Sprite(Device);
Texture = new ImageTexture(Device);
MessageFont = new Font(Device, 16, 0, FontWeight.Bold, 1, false, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Arial");

View File

@ -9,6 +9,97 @@ namespace BizHawk.MultiClient
{
class Throttle
{
int lastskiprate;
int framestoskip;
int framesskipped;
public bool skipnextframe;
public bool signal_frameAdvance;
public bool signal_fastForward;
public bool signal_continuousframeAdvancing; //continuousframeAdvancing
public int cfg_frameskiprate { get { return Global.Config.FrameSkip; } }
public bool cfg_frameLimit { get { return Global.Config.LimitFramerate; } }
public bool cfg_autoframeskipenab { get { return Global.Config.AutoMinimizeSkipping; } }
public void Step(bool allowSleep, int forceFrameSkip)
{
int skipRate = (forceFrameSkip < 0) ? cfg_frameskiprate : forceFrameSkip;
int ffSkipRate = (forceFrameSkip < 0) ? 9 : forceFrameSkip;
if (lastskiprate != skipRate)
{
lastskiprate = skipRate;
framestoskip = 0; // otherwise switches to lower frameskip rates will lag behind
}
if (!skipnextframe || forceFrameSkip == 0 || signal_frameAdvance || (signal_continuousframeAdvancing && !signal_fastForward))
{
framesskipped = 0;
if (framestoskip > 0)
skipnextframe = true;
}
else
{
framestoskip--;
if (framestoskip < 1)
skipnextframe = false;
else
skipnextframe = true;
framesskipped++;
//NDS_SkipNextFrame();
}
if (signal_fastForward)
{
if (framesskipped < ffSkipRate)
{
skipnextframe = true;
framestoskip = 1;
}
if (framestoskip < 1)
framestoskip += ffSkipRate;
}
else if ((/*autoframeskipenab && frameskiprate ||*/ cfg_frameLimit) && allowSleep)
{
SpeedThrottle();
}
if (cfg_autoframeskipenab && cfg_frameskiprate!=0)
{
if (!signal_frameAdvance && !signal_continuousframeAdvancing)
{
AutoFrameSkip_NextFrame();
if (framestoskip < 1)
framestoskip += AutoFrameSkip_GetSkipAmount(0, skipRate);
}
}
else
{
if (framestoskip < 1)
framestoskip += skipRate;
}
if (signal_frameAdvance && allowSleep)
{
//this logic has been replaced by some logic in steprunloop_core.
//really, it should be moved back here somehow later.
//frameAdvance = false;
//emu_halt();
//SPU_Pause(1);
}
//if (execute && emu_paused && !frameAdvance)
//{
// // safety net against running out of control in case this ever happens.
// Unpause(); Pause();
//}
}
static ulong GetCurTime()
{
if (tmethod == 1)
@ -46,11 +137,23 @@ namespace BizHawk.MultiClient
tfreq = afsfreq << 16;
}
public Throttle(float desired_fps)
public Throttle()
{
}
public void SetCoreFps(double desired_fps)
{
core_desiredfps = (ulong)(65536 * desired_fps);
desiredfps = core_desiredfps;
desiredspf = 65536.0f / core_desiredfps;
SetSpeedPercent(pct);
}
int pct = 100;
public void SetSpeedPercent(int percent)
{
pct = percent;
float fraction = percent / 100.0f;
desiredfps = (ulong)(core_desiredfps * fraction);
desiredspf = 65536.0f / desiredfps;
AutoFrameSkip_IgnorePreviousDelay();
}
@ -177,5 +280,37 @@ namespace BizHawk.MultiClient
return rv;
}
void SpeedThrottle()
{
AutoFrameSkip_BeforeThrottle();
waiter:
if (signal_fastForward)
return;
ulong ttime = GetCurTime();
if ((ttime - ltime) < (tfreq / desiredfps))
{
ulong sleepy;
sleepy = (tfreq / desiredfps) - (ttime - ltime);
sleepy *= 1000;
if (tfreq >= 65536)
sleepy /= afsfreq;
else
sleepy = 0;
if (sleepy >= 10)
Thread.Sleep((int)(sleepy / 2)); // reduce it further beacuse Sleep usually sleeps for more than the amount we tell it to
else if (sleepy > 0) // spin for <1 millisecond waits
Thread.Sleep(0);
//SwitchToThread(); // limit to other threads on the same CPU core for other short waits
goto waiter;
}
if ((ttime - ltime) >= (tfreq * 4 / desiredfps))
ltime = ttime;
else
ltime += tfreq / desiredfps;
}
}
}