improve gdi+ rendering mode (depending on your point of view) to run almost as fast as direct3d and put gui option for it

This commit is contained in:
zeromus 2011-03-21 00:54:30 +00:00
parent ad6c2d0faf
commit 1917f7fc2e
6 changed files with 1299 additions and 1169 deletions

View File

@ -50,6 +50,7 @@
public bool DisplayInput = false;
public int DispInpx = 0;
public int DispInpy = 24;
public bool ForceGDI = false;
// Sound options
public bool SoundEnabled = true;

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ namespace BizHawk.MultiClient
{
partial class MainForm
{
private void rAMPokeToolStripMenuItem_Click(object sender, EventArgs e)
private void RAMPokeToolStripMenuItem_Click(object sender, EventArgs e)
{
RamPoke r = new RamPoke();
r.Show();
@ -383,6 +383,48 @@ namespace BizHawk.MultiClient
LoadRom(file.FullName);
}
private void replayInputLogToolStripMenuItem_Click(object sender, EventArgs e)
{
InputLog.StopMovie();
InputLog.StartPlayback();
LoadRom(CurrentlyOpenRom);
}
private void PPUViewerToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadNESPPU();
}
private void enableRewindToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.RewindEnabled ^= true;
}
private void hexEditorToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadHexEditor();
}
private void MainForm_Shown(object sender, EventArgs e)
{
HandlePlatformMenus();
}
private void gameGenieCodesToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadGameGenieEC();
}
private void cheatsToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadCheatsWindow();
}
private void forceGDIPPresentationToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.ForceGDI ^= true;
SyncPresentationMode();
}
}
}

View File

@ -52,6 +52,8 @@ namespace BizHawk.MultiClient
public MainForm(string[] args)
{
InitializeComponent();
//in order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand
//we could background thread this later instead if we wanted to be real clever
NES.BootGodDB.GetDatabaseBytes = () => {
@ -60,28 +62,10 @@ namespace BizHawk.MultiClient
};
Global.MainForm = this;
Global.Config = ConfigService.Load<Config>("config.ini");
if (Global.Direct3D != null)
renderTarget = new ViewportPanel();
else renderTarget = retainedPanel = new RetainedViewportPanel();
renderTarget.Dock = DockStyle.Fill;
renderTarget.BackColor = Color.Black;
Controls.Add(renderTarget);
InitializeComponent();
Database.LoadDatabase("gamedb.txt");
if (Global.Direct3D != null)
{
Global.RenderPanel = new Direct3DRenderPanel(Global.Direct3D, renderTarget);
}
else
{
Global.RenderPanel = new SysdrawingRenderPanel(retainedPanel);
}
SyncPresentationMode();
Load += (o, e) =>
{
@ -160,6 +144,44 @@ namespace BizHawk.MultiClient
PauseEmulator();
}
void SyncPresentationMode()
{
bool gdi = Global.Config.ForceGDI;
if (Global.Direct3D == null)
{
gdi = Global.Config.ForceGDI = true;
}
if (renderTarget != null)
{
renderTarget.Dispose();
Controls.Remove(renderTarget);
}
if (retainedPanel != null) retainedPanel.Dispose();
if (Global.RenderPanel != null) Global.RenderPanel.Dispose();
if (gdi)
renderTarget = retainedPanel = new RetainedViewportPanel();
else renderTarget = new ViewportPanel();
Controls.Add(renderTarget);
Controls.SetChildIndex(renderTarget, 0);
renderTarget.Dock = DockStyle.Fill;
renderTarget.BackColor = Color.Black;
if (gdi)
{
Global.RenderPanel = new SysdrawingRenderPanel(retainedPanel);
retainedPanel.ActivateThreaded();
}
else
{
Global.RenderPanel = new Direct3DRenderPanel(Global.Direct3D, renderTarget);
}
}
void SetSpeedPercent(int value)
{
Global.Config.SpeedPercent = value;
@ -503,7 +525,7 @@ namespace BizHawk.MultiClient
Global.Game.Name = (Global.Emulator as NES).GameName;
}
Text = DisplayNameForSystem(game.System) + " - " + game.Name;
Text = DisplayNameForSystem(game.System) + " - " + game.Name + " \\";
ResetRewindBuffer();
Global.Config.RecentRoms.Add(file.CanonicalName);
if (File.Exists(game.SaveRamPath))
@ -731,6 +753,8 @@ namespace BizHawk.MultiClient
{
runloop_second = DateTime.Now;
Global.RenderPanel.FPS = runloop_fps;
Text = Text.Substring(0, Text.IndexOf('\\')) + "\\ " + runloop_fps + " fps";
Global.RenderPanel.FPS = runloop_fps;
runloop_fps = 0;
}
@ -1179,6 +1203,7 @@ namespace BizHawk.MultiClient
saveWindowPositionToolStripMenuItem.Checked = Global.Config.SaveWindowPosition;
startPausedToolStripMenuItem.Checked = Global.Config.StartPaused;
enableRewindToolStripMenuItem.Checked = Global.Config.RewindEnabled;
forceGDIPPresentationToolStripMenuItem.Checked = Global.Config.ForceGDI;
}
private void MainForm_Load(object sender, EventArgs e)
@ -1245,41 +1270,6 @@ namespace BizHawk.MultiClient
ConfigService.Save("config.ini", Global.Config);
}
private void replayInputLogToolStripMenuItem_Click(object sender, EventArgs e)
{
InputLog.StopMovie();
InputLog.StartPlayback();
LoadRom(CurrentlyOpenRom);
}
private void pPUViewerToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadNESPPU();
}
private void enableRewindToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.RewindEnabled ^= true;
}
private void hexEditorToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadHexEditor();
}
private void MainForm_Shown(object sender, EventArgs e)
{
HandlePlatformMenus();
}
private void gameGenieCodesToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadGameGenieEC();
}
private void cheatsToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadCheatsWindow();
}
}
}

View File

@ -13,16 +13,20 @@ namespace BizHawk.MultiClient
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Global.Config = ConfigService.Load<Config>("config.ini");
try { Global.DSound = new DirectSound(); }
catch {
MessageBox.Show("Couldn't initialize DirectSound!");
return;
}
try { Global.Direct3D = new Direct3D(); }
catch {
//can fallback to GDI rendering
}
try { Global.Direct3D = new Direct3D(); }
catch
{
//can fallback to GDI rendering
Global.Config.ForceGDI = true;
}
try {
var mf = new MainForm(args);

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
@ -11,17 +13,96 @@ namespace BizHawk.Core
/// </summary>
public class RetainedViewportPanel : Control
{
Thread threadPaint;
EventWaitHandle ewh;
volatile bool killSignal;
/// <summary>
/// Turns this panel into multi-threaded mode.
/// This will sort of glitch out other gdi things on the system, but at least its fast...
/// </summary>
public void ActivateThreaded()
{
ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
threadPaint = new Thread(PaintProc);
threadPaint.Start();
}
public RetainedViewportPanel()
{
CreateHandle();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.DoubleBuffer, false);
SetStyle(ControlStyles.Opaque, true);
SetStyle(ControlStyles.UserMouse, true);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (threadPaint != null)
{
killSignal = true;
ewh.Set();
ewh.WaitOne();
}
CleanupDisposeQueue();
}
void DoPaint()
{
if (bmp != null)
{
using (Graphics g = CreateGraphics())
{
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.CompositingMode = CompositingMode.SourceCopy;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.DrawImage(bmp, 0, 0, Width, Height);
}
}
CleanupDisposeQueue();
}
void PaintProc()
{
for (; ; )
{
ewh.WaitOne();
if (killSignal)
{
ewh.Set();
return;
}
DoPaint();
}
}
void CleanupDisposeQueue()
{
lock (this)
{
while (DisposeQueue.Count > 0)
DisposeQueue.Dequeue().Dispose();
}
}
Queue<Bitmap> DisposeQueue = new Queue<Bitmap>();
void SignalPaint()
{
if (threadPaint == null)
DoPaint();
else
ewh.Set();
}
//Size logicalSize;
////int pitch;
//public void SetLogicalSize(int w, int h)
@ -36,24 +117,26 @@ namespace BizHawk.Core
/// </summary>
public void SetBitmap(Bitmap newbmp)
{
if (bmp != null) bmp.Dispose();
bmp = newbmp;
Refresh();
lock (this)
{
if(bmp != null) DisposeQueue.Enqueue(bmp);
bmp = newbmp;
}
SignalPaint();
}
Bitmap bmp;
protected override void OnPaintBackground(PaintEventArgs pevent)
{
}
protected override void OnPaint(PaintEventArgs e)
{
SignalPaint();
base.OnPaint(e);
if (bmp != null)
{
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.CompositingMode = CompositingMode.SourceCopy;
e.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
e.Graphics.DrawImage(bmp, 0, 0, Width, Height);
}
}
}