TAStudio - more misc stuff

This commit is contained in:
andres.delikat 2011-06-12 00:14:19 +00:00
parent cd849d9614
commit 38ca651aab
6 changed files with 593 additions and 550 deletions

View File

@ -12,97 +12,97 @@ using BizHawk.Core;
namespace BizHawk.MultiClient
{
public class ImageTexture : IDisposable
{
public Device GraphicsDevice;
public Texture Texture;
public class ImageTexture : IDisposable
{
public Device GraphicsDevice;
public Texture Texture;
private int imageWidth;
public int ImageWidth { get { return imageWidth; } }
private int imageWidth;
public int ImageWidth { get { return imageWidth; } }
private int imageHeight;
public int ImageHeight { get { return imageHeight; } }
private int imageHeight;
public int ImageHeight { get { return imageHeight; } }
private int textureWidth;
public int TextureWidth { get { return textureWidth; } }
private int textureWidth;
public int TextureWidth { get { return textureWidth; } }
private int textureHeight;
public int TextureHeight { get { return textureHeight; } }
private int textureHeight;
public int TextureHeight { get { return textureHeight; } }
public ImageTexture(Device graphicsDevice)
{
GraphicsDevice = graphicsDevice;
}
public ImageTexture(Device graphicsDevice)
{
GraphicsDevice = graphicsDevice;
}
public void SetImage(int[] data, int width, int height)
{
bool needsRecreating = false;
if (Texture == null)
{
needsRecreating = true;
}
else
{
var currentTextureSize = Texture.GetLevelDescription(0);
if (imageWidth != width || imageHeight != height)
{
needsRecreating = true;
}
}
// If we need to recreate the texture, do so.
if (needsRecreating)
{
if (Texture != null)
{
Texture.Dispose();
Texture = null;
}
// Copy the width/height to member fields.
imageWidth = width;
imageHeight = height;
// Round up the width/height to the nearest power of two.
textureWidth = 32; textureHeight = 32;
while (textureWidth < imageWidth) textureWidth <<= 1;
while (textureHeight < imageHeight) textureHeight <<= 1;
// Create a new texture instance.
Texture = new Texture(GraphicsDevice, textureWidth, textureHeight, 1, Usage.Dynamic, Format.X8R8G8B8, Pool.Default);
}
// Copy the image data to the texture.
using (var Data = Texture.LockRectangle(0, new Rectangle(0, 0, imageWidth, imageHeight), LockFlags.None).Data)
{
if (imageWidth == textureWidth)
{
// Widths are the same, just dump the data across (easy!)
Data.WriteRange(data, 0, imageWidth * imageHeight);
}
else
{
// Widths are different, need a bit of additional magic here to make them fit:
long RowSeekOffset = 4 * (textureWidth - imageWidth);
for (int r = 0, s = 0; r < imageHeight; ++r, s += imageWidth)
{
Data.WriteRange(data, s, imageWidth);
Data.Seek(RowSeekOffset, SeekOrigin.Current);
}
}
Texture.UnlockRectangle(0);
}
}
public void SetImage(int[] data, int width, int height)
{
bool needsRecreating = false;
if (Texture == null)
{
needsRecreating = true;
}
else
{
var currentTextureSize = Texture.GetLevelDescription(0);
if (imageWidth != width || imageHeight != height)
{
needsRecreating = true;
}
}
// If we need to recreate the texture, do so.
if (needsRecreating)
{
if (Texture != null)
{
Texture.Dispose();
Texture = null;
}
// Copy the width/height to member fields.
imageWidth = width;
imageHeight = height;
// Round up the width/height to the nearest power of two.
textureWidth = 32; textureHeight = 32;
while (textureWidth < imageWidth) textureWidth <<= 1;
while (textureHeight < imageHeight) textureHeight <<= 1;
// Create a new texture instance.
Texture = new Texture(GraphicsDevice, textureWidth, textureHeight, 1, Usage.Dynamic, Format.X8R8G8B8, Pool.Default);
}
// Copy the image data to the texture.
using (var Data = Texture.LockRectangle(0, new Rectangle(0, 0, imageWidth, imageHeight), LockFlags.None).Data)
{
if (imageWidth == textureWidth)
{
// Widths are the same, just dump the data across (easy!)
Data.WriteRange(data, 0, imageWidth * imageHeight);
}
else
{
// Widths are different, need a bit of additional magic here to make them fit:
long RowSeekOffset = 4 * (textureWidth - imageWidth);
for (int r = 0, s = 0; r < imageHeight; ++r, s += imageWidth)
{
Data.WriteRange(data, s, imageWidth);
Data.Seek(RowSeekOffset, SeekOrigin.Current);
}
}
Texture.UnlockRectangle(0);
}
}
private bool disposed;
private bool disposed;
public void Dispose()
{
if (!disposed)
{
disposed = true;
if (Texture != null)
Texture.Dispose();
Texture = null;
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
if (Texture != null)
Texture.Dispose();
Texture = null;
GC.SuppressFinalize(this);
}
}
}
public interface IRenderer : IDisposable
{
@ -119,8 +119,8 @@ namespace BizHawk.MultiClient
public string FPS { get; set; }
public void Render(IVideoProvider video)
{
Color BackgroundColor = Color.FromArgb(video.BackgroundColor);
int[] data = video.GetVideoBuffer();
Color BackgroundColor = Color.FromArgb(video.BackgroundColor);
int[] data = video.GetVideoBuffer();
Bitmap bmp = new Bitmap(video.BufferWidth, video.BufferHeight, PixelFormat.Format32bppArgb);
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
@ -142,287 +142,287 @@ namespace BizHawk.MultiClient
public class Direct3DRenderPanel : IRenderer
{
public Color BackgroundColor { get; set; }
public bool Resized { get; set; }
{
public Color BackgroundColor { get; set; }
public bool Resized { get; set; }
public string FPS { get; set; }
private Direct3D d3d;
private Device Device;
private Control backingControl;
public ImageTexture Texture;
private Sprite Sprite;
private Font MessageFont;
private Font AlertFont;
private Direct3D d3d;
private Device Device;
private Control backingControl;
public ImageTexture Texture;
private Sprite Sprite;
private Font MessageFont;
private Font AlertFont;
public Direct3DRenderPanel(Direct3D direct3D, Control control)
{
d3d = direct3D;
backingControl = control;
control.DoubleClick += (o, e) => Global.MainForm.ToggleFullscreen();
}
{
d3d = direct3D;
backingControl = control;
control.DoubleClick += (o, e) => Global.MainForm.ToggleFullscreen();
}
private void DestroyDevice()
{
if (Texture != null)
{
Texture.Dispose();
Texture = null;
}
if (Sprite != null)
{
Sprite.Dispose();
Sprite = null;
}
if (MessageFont != null)
{
MessageFont.Dispose();
MessageFont = null;
}
if (Device != null)
{
Device.Dispose();
Device = null;
}
}
private void DestroyDevice()
{
if (Texture != null)
{
Texture.Dispose();
Texture = null;
}
if (Sprite != null)
{
Sprite.Dispose();
Sprite = null;
}
if (MessageFont != null)
{
MessageFont.Dispose();
MessageFont = null;
}
if (Device != null)
{
Device.Dispose();
Device = null;
}
}
public void CreateDevice()
{
DestroyDevice();
public void CreateDevice()
{
DestroyDevice();
var pp = new PresentParameters
{
BackBufferWidth = Math.Max(1, backingControl.ClientSize.Width),
BackBufferHeight = Math.Max(1, backingControl.ClientSize.Height),
DeviceWindowHandle = backingControl.Handle,
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, "Courier");
AlertFont = new Font(Device, 20, 0, FontWeight.ExtraBold, 1, true, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier");
}
{
BackBufferWidth = Math.Max(1, backingControl.ClientSize.Width),
BackBufferHeight = Math.Max(1, backingControl.ClientSize.Height),
DeviceWindowHandle = backingControl.Handle,
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, "Courier");
AlertFont = new Font(Device, 20, 0, FontWeight.ExtraBold, 1, true, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.Default | PitchAndFamily.DontCare, "Courier");
}
public void Render()
{
if (Device == null || Resized)
CreateDevice();
public void Render()
{
if (Device == null || Resized)
CreateDevice();
Resized = false;
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
Device.Present(Present.DoNotWait);
}
Resized = false;
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
Device.Present(Present.DoNotWait);
}
public void Render(IVideoProvider video)
{
if (video == null)
{
Render();
return;
}
public void Render(IVideoProvider video)
{
if (video == null)
{
Render();
return;
}
if (Device == null || Resized)
CreateDevice();
Resized = false;
if (Device == null || Resized)
CreateDevice();
Resized = false;
BackgroundColor = Color.FromArgb(video.BackgroundColor);
BackgroundColor = Color.FromArgb(video.BackgroundColor);
int[] data = video.GetVideoBuffer();
Texture.SetImage(data, video.BufferWidth, video.BufferHeight);
int[] data = video.GetVideoBuffer();
Texture.SetImage(data, video.BufferWidth, video.BufferHeight);
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
// figure out scaling factor
float widthScale = (float) backingControl.Size.Width / video.BufferWidth;
float heightScale = (float) backingControl.Size.Height / video.BufferHeight;
float finalScale = Math.Min(widthScale, heightScale);
// figure out scaling factor
float widthScale = (float)backingControl.Size.Width / video.BufferWidth;
float heightScale = (float)backingControl.Size.Height / video.BufferHeight;
float finalScale = Math.Min(widthScale, heightScale);
Device.BeginScene();
Device.BeginScene();
Sprite.Begin(SpriteFlags.None);
Device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Point);
Device.SetSamplerState(1, SamplerState.MagFilter, TextureFilter.Point);
Sprite.Transform = Matrix.Scaling(finalScale, finalScale, 0f);
Sprite.Draw(Texture.Texture, new Rectangle(0, 0, video.BufferWidth, video.BufferHeight), new Vector3(video.BufferWidth / 2f, video.BufferHeight / 2f, 0), new Vector3(backingControl.Size.Width / 2f / finalScale, backingControl.Size.Height / 2f / finalScale, 0), Color.White);
Sprite.End();
Sprite.Begin(SpriteFlags.None);
Device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Point);
Device.SetSamplerState(1, SamplerState.MagFilter, TextureFilter.Point);
Sprite.Transform = Matrix.Scaling(finalScale, finalScale, 0f);
Sprite.Draw(Texture.Texture, new Rectangle(0, 0, video.BufferWidth, video.BufferHeight), new Vector3(video.BufferWidth / 2f, video.BufferHeight / 2f, 0), new Vector3(backingControl.Size.Width / 2f / finalScale, backingControl.Size.Height / 2f / finalScale, 0), Color.White);
Sprite.End();
DrawMessages();
DrawMessages();
Device.EndScene();
Device.Present(Present.DoNotWait);
}
Device.EndScene();
Device.Present(Present.DoNotWait);
}
/// <summary>
/// Display all screen info objects like fps, frame counter, lag counter, and input display
/// </summary>
public void DrawScreenInfo()
{
//TODO: If movie loaded use that frame counter, and also display total movie frame count if read-only
if (Global.Config.DisplayFrameCounter)
{
MessageFont.DrawString(null, MakeFrameCounter(), Global.Config.DispFrameCx+1,
Global.Config.DispFrameCy+1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeFrameCounter(), Global.Config.DispFrameCx,
Global.Config.DispFrameCy, Color.FromArgb(Global.Config.MessagesColor));
}
if (Global.Config.DisplayInput)
{
string input = MakeLastInputDisplay();
Color c;
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
c = Color.Gray;
}
else
c = Color.FromArgb(Global.Config.MessagesColor);
MessageFont.DrawString(null, input, Global.Config.DispInpx+2, Global.Config.DispInpy+2, new Color4(Color.Black));
MessageFont.DrawString(null, input, Global.Config.DispInpx+1, Global.Config.DispInpy+1, Color.FromArgb(Global.Config.LastInputColor));
input = MakeInputDisplay();
MessageFont.DrawString(null, input, Global.Config.DispInpx, Global.Config.DispInpy, c);
}
/// <summary>
/// Display all screen info objects like fps, frame counter, lag counter, and input display
/// </summary>
public void DrawScreenInfo()
{
//TODO: If movie loaded use that frame counter, and also display total movie frame count if read-only
if (Global.Config.DisplayFrameCounter)
{
MessageFont.DrawString(null, MakeFrameCounter(), Global.Config.DispFrameCx + 1,
Global.Config.DispFrameCy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeFrameCounter(), Global.Config.DispFrameCx,
Global.Config.DispFrameCy, Color.FromArgb(Global.Config.MessagesColor));
}
if (Global.Config.DisplayInput)
{
string input = MakeLastInputDisplay();
Color c;
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
c = Color.Gray;
}
else
c = Color.FromArgb(Global.Config.MessagesColor);
if (Global.Config.DisplayFPS)
{
MessageFont.DrawString(null, FPS, Global.Config.DispFPSx + 1,
Global.Config.DispFPSy+1, new Color4(Color.Black));
MessageFont.DrawString(null, FPS, Global.Config.DispFPSx,
Global.Config.DispFPSy, Color.FromArgb(Global.Config.MessagesColor));
}
MessageFont.DrawString(null, input, Global.Config.DispInpx + 2, Global.Config.DispInpy + 2, new Color4(Color.Black));
MessageFont.DrawString(null, input, Global.Config.DispInpx + 1, Global.Config.DispInpy + 1, Color.FromArgb(Global.Config.LastInputColor));
input = MakeInputDisplay();
MessageFont.DrawString(null, input, Global.Config.DispInpx, Global.Config.DispInpy, c);
}
if (Global.Config.DisplayLagCounter)
{
if (Global.Emulator.IsLagFrame)
{
AlertFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx + 1,
Global.Config.DispLagy + 1, new Color4(Color.Black));
AlertFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx,
Global.Config.DispLagy, Color.FromArgb(Global.Config.AlertMessageColor));
}
else
{
MessageFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx + 1,
Global.Config.DispLagy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx,
Global.Config.DispLagy, Color.FromArgb(Global.Config.MessagesColor));
}
}
if (Global.Config.DisplayRerecordCount)
{
MessageFont.DrawString(null, MakeRerecordCount(), Global.Config.DispRecx + 1,
Global.Config.DispRecy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeRerecordCount(), Global.Config.DispRecx,
Global.Config.DispRecy, Color.FromArgb(Global.Config.MessagesColor));
}
//TODO: clean this up or replace with simple draw symbols
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY
|| Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
MessageFont.DrawString(null, "Playback", 208 + 1,
0 + 1, new Color4(Color.Black));
MessageFont.DrawString(null, "Playback", 208,
0, new Color4(Color.Red));
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.RECORD)
{
AlertFont.DrawString(null, "Recording", 208 + 1,
0 + 1, new Color4(Color.Black));
AlertFont.DrawString(null, "Recording", 208,
0, new Color4(Color.Red));
}
}
if (Global.Config.DisplayFPS)
{
MessageFont.DrawString(null, FPS, Global.Config.DispFPSx + 1,
Global.Config.DispFPSy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, FPS, Global.Config.DispFPSx,
Global.Config.DispFPSy, Color.FromArgb(Global.Config.MessagesColor));
}
private string MakeFrameCounter()
{
//TODO: remove rerecord count code and make it its own display option
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.FINISHED)
{
return Global.Emulator.Frame.ToString() + "/" + Global.MainForm.UserMovie.GetMovieLength().ToString() + " (Finished)";
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
return "E" + Global.Emulator.Frame.ToString() + " " + Global.MainForm.UserMovie.lastLog.ToString()
+ "/" + Global.MainForm.UserMovie.GetMovieLength().ToString();
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.RECORD)
return "E" + Global.Emulator.Frame.ToString() + " " + Global.MainForm.UserMovie.lastLog.ToString() +
" length: " + Global.MainForm.UserMovie.GetMovieLength().ToString();
else
{
return Global.Emulator.Frame.ToString();
}
}
if (Global.Config.DisplayLagCounter)
{
if (Global.Emulator.IsLagFrame)
{
AlertFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx + 1,
Global.Config.DispLagy + 1, new Color4(Color.Black));
AlertFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx,
Global.Config.DispLagy, Color.FromArgb(Global.Config.AlertMessageColor));
}
else
{
MessageFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx + 1,
Global.Config.DispLagy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeLagCounter(), Global.Config.DispLagx,
Global.Config.DispLagy, Color.FromArgb(Global.Config.MessagesColor));
}
private string MakeLagCounter()
{
return Global.Emulator.LagCount.ToString();
}
}
if (Global.Config.DisplayRerecordCount)
{
MessageFont.DrawString(null, MakeRerecordCount(), Global.Config.DispRecx + 1,
Global.Config.DispRecy + 1, new Color4(Color.Black));
MessageFont.DrawString(null, MakeRerecordCount(), Global.Config.DispRecx,
Global.Config.DispRecy, Color.FromArgb(Global.Config.MessagesColor));
}
private List<UIMessage> messages = new List<UIMessage>(5);
//TODO: clean this up or replace with simple draw symbols
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY
|| Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
MessageFont.DrawString(null, "Playback", 208 + 1,
0 + 1, new Color4(Color.Black));
MessageFont.DrawString(null, "Playback", 208,
0, new Color4(Color.Red));
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.RECORD)
{
AlertFont.DrawString(null, "Recording", 208 + 1,
0 + 1, new Color4(Color.Black));
AlertFont.DrawString(null, "Recording", 208,
0, new Color4(Color.Red));
}
}
public void AddMessage(string message)
{
messages.Add(new UIMessage {Message = message, ExpireAt = DateTime.Now + TimeSpan.FromSeconds(2)});
}
private string MakeFrameCounter()
{
//TODO: remove rerecord count code and make it its own display option
if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.FINISHED)
{
return Global.Emulator.Frame.ToString() + "/" + Global.MainForm.UserMovie.GetMovieLength().ToString() + " (Finished)";
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)
{
return "E" + Global.Emulator.Frame.ToString() + " " + Global.MainForm.UserMovie.lastLog.ToString()
+ "/" + Global.MainForm.UserMovie.GetMovieLength().ToString();
}
else if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.RECORD)
return "E" + Global.Emulator.Frame.ToString() + " " + Global.MainForm.UserMovie.lastLog.ToString() +
" length: " + Global.MainForm.UserMovie.GetMovieLength().ToString();
else
{
return Global.Emulator.Frame.ToString();
}
}
private void DrawMessages()
{
messages.RemoveAll(m => DateTime.Now > m.ExpireAt);
DrawScreenInfo();
int line = 1;
for (int i=messages.Count - 1; i>=0; i--, line++)
{
int x = 3;
int y = backingControl.Size.Height - (line*18);
MessageFont.DrawString(null, messages[i].Message, x+2, y+2, new Color4(Color.Black));
MessageFont.DrawString(null, messages[i].Message, x, y, Color.FromArgb(Global.Config.MessagesColor));
}
}
private string MakeLagCounter()
{
return Global.Emulator.LagCount.ToString();
}
private bool disposed;
private List<UIMessage> messages = new List<UIMessage>(5);
public void Dispose()
{
if (disposed == false)
{
disposed = true;
DestroyDevice();
}
}
public void AddMessage(string message)
{
messages.Add(new UIMessage { Message = message, ExpireAt = DateTime.Now + TimeSpan.FromSeconds(2) });
}
public string MakeInputDisplay()
{
string tmp = Global.ActiveController.GetControllersAsMnemonic();
tmp = tmp.Replace(".", " ");
tmp = tmp.Replace("|", "");
return tmp;
}
private void DrawMessages()
{
messages.RemoveAll(m => DateTime.Now > m.ExpireAt);
DrawScreenInfo();
int line = 1;
for (int i = messages.Count - 1; i >= 0; i--, line++)
{
int x = 3;
int y = backingControl.Size.Height - (line * 18);
MessageFont.DrawString(null, messages[i].Message, x + 2, y + 2, new Color4(Color.Black));
MessageFont.DrawString(null, messages[i].Message, x, y, Color.FromArgb(Global.Config.MessagesColor));
}
}
public string MakeLastInputDisplay()
{
string tmp = Global.MainForm.wasPressed;
tmp = tmp.Replace(".", " ");
tmp = tmp.Replace("|", "");
return tmp;
}
private bool disposed;
public string MakeRerecordCount()
{
string tmp = "";
if (Global.MainForm.UserMovie.GetMovieMode() != MOVIEMODE.INACTIVE)
{
tmp += "Rerecord Count: ";
tmp += Global.MainForm.GetActiveMovie().GetRerecordCount().ToString();
}
return tmp;
}
}
public void Dispose()
{
if (disposed == false)
{
disposed = true;
DestroyDevice();
}
}
class UIMessage
{
public string Message;
public DateTime ExpireAt;
}
public string MakeInputDisplay()
{
string tmp = Global.ActiveController.GetControllersAsMnemonic();
tmp = tmp.Replace(".", " ");
tmp = tmp.Replace("|", "");
return tmp;
}
public string MakeLastInputDisplay()
{
string tmp = Global.MainForm.wasPressed;
tmp = tmp.Replace(".", " ");
tmp = tmp.Replace("|", "");
return tmp;
}
public string MakeRerecordCount()
{
string tmp = "";
if (Global.MainForm.UserMovie.GetMovieMode() != MOVIEMODE.INACTIVE)
{
tmp += "Rerecord Count: ";
tmp += Global.MainForm.GetActiveMovie().GetRerecordCount().ToString();
}
return tmp;
}
}
class UIMessage
{
public string Message;
public DateTime ExpireAt;
}
}

View File

@ -2,173 +2,173 @@
namespace BizHawk.MultiClient
{
public partial class MainForm
{
private MruStack<MemoryStream> RewindBuf = new MruStack<MemoryStream>(15000);
private byte[] LastState;
public partial class MainForm
{
private MruStack<MemoryStream> RewindBuf = new MruStack<MemoryStream>(15000);
private byte[] LastState;
private void CaptureRewindState()
{
if (LastState == null)
{
// This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against.
LastState = Global.Emulator.SaveStateBinary();
//System.Console.WriteLine(LastState.Length);
return;
}
private void CaptureRewindState()
{
if (LastState == null)
{
// This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against.
LastState = Global.Emulator.SaveStateBinary();
//System.Console.WriteLine(LastState.Length);
return;
}
// Otherwise, it's not the first frame, so build a delta.
if (LastState.Length <= 0x10000)
CaptureRewindState64K();
else
CaptureRewindStateLarge();
}
// Otherwise, it's not the first frame, so build a delta.
if (LastState.Length <= 0x10000)
CaptureRewindState64K();
else
CaptureRewindStateLarge();
}
/// <summary>
/// Builds a delta for states that are <= 64K in size.
/// </summary>
private void CaptureRewindState64K()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
{
/// <summary>
/// Builds a delta for states that are <= 64K in size.
/// </summary>
private void CaptureRewindState64K()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
{
if (i >= LastState.Length)
continue;
if (CurrentState[i] == LastState[i])
continue;
if (CurrentState[i] == LastState[i])
continue;
inChangeSequence = true;
beginChangeSequence = i;
continue;
}
inChangeSequence = true;
beginChangeSequence = i;
continue;
}
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
{
writer.Write((byte)(i - beginChangeSequence + 1));
writer.Write((ushort)beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
inChangeSequence = false;
continue;
}
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
{
writer.Write((byte)(i - beginChangeSequence + 1));
writer.Write((ushort)beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
inChangeSequence = false;
continue;
}
if (CurrentState[i] == LastState[i])
{
writer.Write((byte)(i - beginChangeSequence));
writer.Write((ushort)beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
inChangeSequence = false;
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
}
if (CurrentState[i] == LastState[i])
{
writer.Write((byte)(i - beginChangeSequence));
writer.Write((ushort)beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
inChangeSequence = false;
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
}
/// <summary>
/// Builds a delta for states that are > 64K in size.
/// </summary>
private void CaptureRewindStateLarge()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
{
/// <summary>
/// Builds a delta for states that are > 64K in size.
/// </summary>
private void CaptureRewindStateLarge()
{
byte[] CurrentState = Global.Emulator.SaveStateBinary();
int beginChangeSequence = -1;
bool inChangeSequence = false;
var ms = new MemoryStream();
var writer = new BinaryWriter(ms);
for (int i = 0; i < CurrentState.Length; i++)
{
if (inChangeSequence == false)
{
if (i >= LastState.Length)
continue;
if (CurrentState[i] == LastState[i])
continue;
if (CurrentState[i] == LastState[i])
continue;
inChangeSequence = true;
beginChangeSequence = i;
continue;
}
inChangeSequence = true;
beginChangeSequence = i;
continue;
}
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
{
writer.Write((byte)(i - beginChangeSequence + 1));
writer.Write(beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
inChangeSequence = false;
continue;
}
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
{
writer.Write((byte)(i - beginChangeSequence + 1));
writer.Write(beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
inChangeSequence = false;
continue;
}
if (CurrentState[i] == LastState[i])
{
writer.Write((byte)(i - beginChangeSequence));
writer.Write(beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
inChangeSequence = false;
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
}
if (CurrentState[i] == LastState[i])
{
writer.Write((byte)(i - beginChangeSequence));
writer.Write(beginChangeSequence);
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
inChangeSequence = false;
}
}
LastState = CurrentState;
ms.Position = 0;
RewindBuf.Push(ms);
}
private void Rewind64K()
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
byte len = reader.ReadByte();
ushort offset = reader.ReadUInt16();
output.Position = offset;
output.Write(ms.GetBuffer(), (int)ms.Position, len);
ms.Position += len;
}
reader.Close();
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
private void Rewind64K()
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
byte len = reader.ReadByte();
ushort offset = reader.ReadUInt16();
output.Position = offset;
output.Write(ms.GetBuffer(), (int)ms.Position, len);
ms.Position += len;
}
reader.Close();
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
private void RewindLarge()
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
byte len = reader.ReadByte();
int offset = reader.ReadInt32();
output.Position = offset;
output.Write(ms.GetBuffer(), (int)ms.Position, len);
ms.Position += len;
}
reader.Close();
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
private void RewindLarge()
{
var ms = RewindBuf.Pop();
var reader = new BinaryReader(ms);
var output = new MemoryStream(LastState);
while (ms.Position < ms.Length - 1)
{
byte len = reader.ReadByte();
int offset = reader.ReadInt32();
output.Position = offset;
output.Write(ms.GetBuffer(), (int)ms.Position, len);
ms.Position += len;
}
reader.Close();
output.Position = 0;
Global.Emulator.LoadStateBinary(new BinaryReader(output));
}
private void Rewind(int frames)
{
for (int i = 0; i < frames; i++)
{
if (RewindBuf.Count == 0)
return;
if (LastState.Length < 0x10000)
Rewind64K();
else
RewindLarge();
}
}
public void Rewind(int frames)
{
for (int i = 0; i < frames; i++)
{
if (RewindBuf.Count == 0)
return;
if (LastState.Length < 0x10000)
Rewind64K();
else
RewindLarge();
}
}
public void ResetRewindBuffer()
{
RewindBuf.Clear();
LastState = null;
}
}
public void ResetRewindBuffer()
{
RewindBuf.Clear();
LastState = null;
}
}
}

View File

@ -9,65 +9,65 @@ using System.Windows.Forms;
namespace BizHawk.MultiClient
{
public partial class SoundConfig : Form
{
public SoundConfig()
{
InitializeComponent();
}
public partial class SoundConfig : Form
{
public SoundConfig()
{
InitializeComponent();
}
private void SoundConfig_Load(object sender, EventArgs e)
{
SoundOnCheckBox.Checked = Global.Config.SoundEnabled;
MuteFrameAdvance.Checked = Global.Config.MuteFrameAdvance;
SoundVolBar.Value = Global.Config.SoundVolume;
SoundVolNumeric.Value = Global.Config.SoundVolume;
UpdateSoundDialog();
}
private void SoundConfig_Load(object sender, EventArgs e)
{
SoundOnCheckBox.Checked = Global.Config.SoundEnabled;
MuteFrameAdvance.Checked = Global.Config.MuteFrameAdvance;
SoundVolBar.Value = Global.Config.SoundVolume;
SoundVolNumeric.Value = Global.Config.SoundVolume;
UpdateSoundDialog();
}
private void OK_Click(object sender, EventArgs e)
{
Global.Config.SoundEnabled = SoundOnCheckBox.Checked;
Global.Config.MuteFrameAdvance = MuteFrameAdvance.Checked;
Global.Config.SoundVolume = SoundVolBar.Value;
Global.Sound.ChangeVolume(Global.Config.SoundVolume);
Global.Sound.UpdateSoundSettings();
Global.Sound.StartSound();
this.Close();
}
private void OK_Click(object sender, EventArgs e)
{
Global.Config.SoundEnabled = SoundOnCheckBox.Checked;
Global.Config.MuteFrameAdvance = MuteFrameAdvance.Checked;
Global.Config.SoundVolume = SoundVolBar.Value;
Global.Sound.ChangeVolume(Global.Config.SoundVolume);
Global.Sound.UpdateSoundSettings();
Global.Sound.StartSound();
this.Close();
}
private void Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
SoundVolNumeric.Value = SoundVolBar.Value;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
SoundVolNumeric.Value = SoundVolBar.Value;
}
private void SoundVolNumeric_ValueChanged(object sender, EventArgs e)
{
SoundVolBar.Value = (int)SoundVolNumeric.Value;
}
private void SoundVolNumeric_ValueChanged(object sender, EventArgs e)
{
SoundVolBar.Value = (int)SoundVolNumeric.Value;
}
private void SoundOnCheckBox_CheckedChanged(object sender, EventArgs e)
{
UpdateSoundDialog();
}
private void SoundOnCheckBox_CheckedChanged(object sender, EventArgs e)
{
UpdateSoundDialog();
}
private void UpdateSoundDialog()
{
if (SoundOnCheckBox.Checked)
{
SoundVolGroup.Enabled = true;
MuteFrameAdvance.Enabled = true;
}
else
{
SoundVolGroup.Enabled = false;
MuteFrameAdvance.Enabled = false;
}
}
}
private void UpdateSoundDialog()
{
if (SoundOnCheckBox.Checked)
{
SoundVolGroup.Enabled = true;
MuteFrameAdvance.Enabled = true;
}
else
{
SoundVolGroup.Enabled = false;
MuteFrameAdvance.Enabled = false;
}
}
}
}

View File

@ -66,11 +66,16 @@
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.ReadOnlyCheckBox = new System.Windows.Forms.CheckBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.insertFrameToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
this.toolStripContainer1.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.toolStrip2.SuspendLayout();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// menuStrip1
@ -81,7 +86,7 @@
this.settingsToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(699, 24);
this.menuStrip1.Size = new System.Drawing.Size(721, 24);
this.menuStrip1.TabIndex = 0;
this.menuStrip1.Text = "menuStrip1";
//
@ -237,7 +242,7 @@
this.TASView.Location = new System.Drawing.Point(22, 38);
this.TASView.Name = "TASView";
this.TASView.selectedItem = -1;
this.TASView.Size = new System.Drawing.Size(399, 424);
this.TASView.Size = new System.Drawing.Size(335, 424);
this.TASView.TabIndex = 1;
this.TASView.UseCompatibleStateImageBehavior = false;
this.TASView.View = System.Windows.Forms.View.Details;
@ -256,10 +261,10 @@
//
// toolStripContainer1.ContentPanel
//
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(172, 125);
this.toolStripContainer1.Location = new System.Drawing.Point(427, 38);
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(172, 39);
this.toolStripContainer1.Location = new System.Drawing.Point(373, 38);
this.toolStripContainer1.Name = "toolStripContainer1";
this.toolStripContainer1.Size = new System.Drawing.Size(172, 175);
this.toolStripContainer1.Size = new System.Drawing.Size(172, 89);
this.toolStripContainer1.TabIndex = 2;
this.toolStripContainer1.Text = "toolStripContainer1";
//
@ -380,7 +385,7 @@
this.ReadOnlyCheckBox.BackColor = System.Drawing.SystemColors.Control;
this.ReadOnlyCheckBox.Image = global::BizHawk.MultiClient.Properties.Resources.ReadOnly;
this.ReadOnlyCheckBox.ImageAlign = System.Drawing.ContentAlignment.BottomRight;
this.ReadOnlyCheckBox.Location = new System.Drawing.Point(605, 38);
this.ReadOnlyCheckBox.Location = new System.Drawing.Point(551, 38);
this.ReadOnlyCheckBox.Name = "ReadOnlyCheckBox";
this.ReadOnlyCheckBox.Size = new System.Drawing.Size(22, 22);
this.ReadOnlyCheckBox.TabIndex = 3;
@ -388,11 +393,37 @@
this.ReadOnlyCheckBox.UseVisualStyleBackColor = false;
this.ReadOnlyCheckBox.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.insertFrameToolStripMenuItem1,
this.toolStripSeparator5,
this.selectAllToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(148, 54);
//
// insertFrameToolStripMenuItem1
//
this.insertFrameToolStripMenuItem1.Name = "insertFrameToolStripMenuItem1";
this.insertFrameToolStripMenuItem1.Size = new System.Drawing.Size(147, 22);
this.insertFrameToolStripMenuItem1.Text = "Insert Frame";
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(144, 6);
//
// selectAllToolStripMenuItem
//
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
this.selectAllToolStripMenuItem.Text = "Select All";
//
// TAStudio
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(699, 474);
this.ClientSize = new System.Drawing.Size(721, 474);
this.Controls.Add(this.ReadOnlyCheckBox);
this.Controls.Add(this.toolStripContainer1);
this.Controls.Add(this.TASView);
@ -412,6 +443,7 @@
this.toolStrip1.PerformLayout();
this.toolStrip2.ResumeLayout(false);
this.toolStrip2.PerformLayout();
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -455,5 +487,9 @@
private System.Windows.Forms.ToolStripButton FastFowardToEnd;
private System.Windows.Forms.ToolStripButton PlayMovieFromBeginning;
private System.Windows.Forms.ToolStripMenuItem insertFrameToolStripMenuItem;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem insertFrameToolStripMenuItem1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem;
}
}

View File

@ -128,12 +128,12 @@ namespace BizHawk.MultiClient
if (ReadOnlyCheckBox.Checked)
{
ReadOnlyCheckBox.BackColor = System.Drawing.SystemColors.Control;
//TODO: set tooltip text to "In Read-Only Mode)
toolTip1.SetToolTip(this.ReadOnlyCheckBox, "Currently Read-Only Mode");
}
else
{
ReadOnlyCheckBox.BackColor = Color.LightCoral;
//TOD: set tooltip text to "In Read+Write Mode"
toolTip1.SetToolTip(this.ReadOnlyCheckBox, "Currently Read+Write Mode");
}
}
@ -144,7 +144,8 @@ namespace BizHawk.MultiClient
private void RewindToBeginning_Click(object sender, EventArgs e)
{
Global.MainForm.Rewind(Global.Emulator.Frame);
DisplayList();
}
private void FastForwardToEnd_Click(object sender, EventArgs e)

View File

@ -145,6 +145,12 @@
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>324, 17</value>
</metadata>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>324, 17</value>
</metadata>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>416, 17</value>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAA