Fix mixed line endings.

This commit is contained in:
J.D. Purcell 2017-04-15 15:53:02 -04:00
parent 5b41b7260b
commit ed3bf0e62b
29 changed files with 6400 additions and 6400 deletions

View File

@ -1,198 +1,198 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
namespace BizHawk.Client.ApiHawk namespace BizHawk.Client.ApiHawk
{ {
/// <summary> /// <summary>
/// This static class handle all ExternalTools /// This static class handle all ExternalTools
/// </summary> /// </summary>
public static class ExternalToolManager public static class ExternalToolManager
{ {
#region Fields #region Fields
private static FileSystemWatcher directoryMonitor; private static FileSystemWatcher directoryMonitor;
private static List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>(); private static List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
#endregion #endregion
#region cTor(s) #region cTor(s)
/// <summary> /// <summary>
/// Initilization /// Initilization
/// </summary> /// </summary>
static ExternalToolManager() static ExternalToolManager()
{ {
if(!Directory.Exists(Global.Config.PathEntries["Global", "External Tools"].Path)) if(!Directory.Exists(Global.Config.PathEntries["Global", "External Tools"].Path))
{
Directory.CreateDirectory(Global.Config.PathEntries["Global", "External Tools"].Path);
}
directoryMonitor = new FileSystemWatcher(Global.Config.PathEntries["Global", "External Tools"].Path, "*.dll");
directoryMonitor.IncludeSubdirectories = false;
directoryMonitor.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
directoryMonitor.Filter = "*.dll";
directoryMonitor.Created += new FileSystemEventHandler(DirectoryMonitor_Created);
directoryMonitor.EnableRaisingEvents = true;
ClientApi.RomLoaded += delegate { BuildToolStrip(); };
BuildToolStrip();
}
#endregion
#region Methods
/// <summary>
/// Build the toolstrip menu
/// </summary>
private static void BuildToolStrip()
{
menuItems.Clear();
if (Directory.Exists(directoryMonitor.Path))
{
DirectoryInfo dInfo = new DirectoryInfo(directoryMonitor.Path);
foreach (FileInfo fi in dInfo.GetFiles("*.dll"))
{
menuItems.Add(GenerateToolTipFromFileName(fi.FullName));
}
}
}
/// <summary>
/// Generate a <see cref="ToolStripMenuItem"/> from an
/// external tool dll.
/// The assembly must have <see cref="BizHawkExternalToolAttribute"/> in its
/// assembly attributes
/// </summary>
/// <param name="fileName">File that will be reflected</param>
/// <returns>A new <see cref="ToolStripMenuItem"/>; assembly path can be found in the Tag property</returns>
/// <remarks>For the moment, you could only load a dll that have a form (which implements <see cref="BizHawk.Client.EmuHawk.IExternalToolForm"/>)</remarks>
private static ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
{
Type customFormType;
Assembly externalToolFile;
ToolStripMenuItem item = null;
try
{ {
BizHawk.Common.Win32Hacks.RemoveMOTW(fileName); Directory.CreateDirectory(Global.Config.PathEntries["Global", "External Tools"].Path);
externalToolFile = Assembly.LoadFrom(fileName); }
object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false); directoryMonitor = new FileSystemWatcher(Global.Config.PathEntries["Global", "External Tools"].Path, "*.dll");
if (attributes != null && attributes.Count() == 1) directoryMonitor.IncludeSubdirectories = false;
{ directoryMonitor.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0]; directoryMonitor.Filter = "*.dll";
item = new ToolStripMenuItem(attribute.Name); directoryMonitor.Created += new FileSystemEventHandler(DirectoryMonitor_Created);
item.ToolTipText = attribute.Description; directoryMonitor.EnableRaisingEvents = true;
if (attribute.IconResourceName != string.Empty)
{ ClientApi.RomLoaded += delegate { BuildToolStrip(); };
Stream s = externalToolFile.GetManifestResourceStream(string.Format("{0}.{1}", externalToolFile.GetName().Name, attribute.IconResourceName));
if (s != null) BuildToolStrip();
{ }
item.Image = new Bitmap(s);
} #endregion
}
#region Methods
customFormType = externalToolFile.GetTypes().FirstOrDefault<Type>(t => t != null && t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm");
if (customFormType == null) /// <summary>
{ /// Build the toolstrip menu
item.ToolTipText = "Does not have a CustomMainForm"; /// </summary>
item.Enabled = false; private static void BuildToolStrip()
} {
item.Tag = fileName; menuItems.Clear();
if (Directory.Exists(directoryMonitor.Path))
attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolUsageAttribute), false); {
if (attributes != null && attributes.Count() == 1) DirectoryInfo dInfo = new DirectoryInfo(directoryMonitor.Path);
{
BizHawkExternalToolUsageAttribute attribute2 = (BizHawkExternalToolUsageAttribute)attributes[0]; foreach (FileInfo fi in dInfo.GetFiles("*.dll"))
if(Global.Emulator.SystemId == "NULL" && attribute2.ToolUsage != BizHawkExternalToolUsage.Global) {
{ menuItems.Add(GenerateToolTipFromFileName(fi.FullName));
item.ToolTipText = "This tool doesn't work if nothing is loaded"; }
item.Enabled = false; }
} }
else if(attribute2.ToolUsage == BizHawkExternalToolUsage.EmulatorSpecific && Global.Emulator.SystemId != ClientApi.SystemIdConverter.ConvertBack(attribute2.System))
{ /// <summary>
item.ToolTipText = "This tool doesn't work for current system"; /// Generate a <see cref="ToolStripMenuItem"/> from an
item.Enabled = false; /// external tool dll.
} /// The assembly must have <see cref="BizHawkExternalToolAttribute"/> in its
else if (attribute2.ToolUsage == BizHawkExternalToolUsage.GameSpecific && Global.Game.Hash != attribute2.GameHash) /// assembly attributes
{ /// </summary>
item.ToolTipText = "This tool doesn't work for current game"; /// <param name="fileName">File that will be reflected</param>
item.Enabled = false; /// <returns>A new <see cref="ToolStripMenuItem"/>; assembly path can be found in the Tag property</returns>
} /// <remarks>For the moment, you could only load a dll that have a form (which implements <see cref="BizHawk.Client.EmuHawk.IExternalToolForm"/>)</remarks>
} private static ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
} {
else Type customFormType;
{ Assembly externalToolFile;
item = new ToolStripMenuItem(externalToolFile.GetName().Name); ToolStripMenuItem item = null;
item.ToolTipText = "BizHawkExternalTool attribute hasn't been found";
item.Enabled = false; try
} {
} BizHawk.Common.Win32Hacks.RemoveMOTW(fileName);
catch (BadImageFormatException) externalToolFile = Assembly.LoadFrom(fileName);
{ object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false);
item = new ToolStripMenuItem(fileName); if (attributes != null && attributes.Count() == 1)
item.ToolTipText = "This is not an assembly"; {
item.Enabled = false; BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0];
} item = new ToolStripMenuItem(attribute.Name);
item.ToolTipText = attribute.Description;
#if DEBUG //I added special debug stuff to get additionnal informations. Don(t think it can be usefull for released versions if (attribute.IconResourceName != string.Empty)
catch (ReflectionTypeLoadException ex) {
{ Stream s = externalToolFile.GetManifestResourceStream(string.Format("{0}.{1}", externalToolFile.GetName().Name, attribute.IconResourceName));
foreach (Exception e in ex.LoaderExceptions) if (s != null)
{ {
Debug.WriteLine(e.Message); item.Image = new Bitmap(s);
} }
item.ToolTipText = "Something goes wrong while trying to load"; }
item.Enabled = false;
} customFormType = externalToolFile.GetTypes().FirstOrDefault<Type>(t => t != null && t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm");
#else if (customFormType == null)
catch (ReflectionTypeLoadException) {
{ item.ToolTipText = "Does not have a CustomMainForm";
item.ToolTipText = "Something goes wrong while trying to load"; item.Enabled = false;
item.Enabled = false; }
} item.Tag = fileName;
#endif
attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolUsageAttribute), false);
return item; if (attributes != null && attributes.Count() == 1)
} {
BizHawkExternalToolUsageAttribute attribute2 = (BizHawkExternalToolUsageAttribute)attributes[0];
/// <summary> if(Global.Emulator.SystemId == "NULL" && attribute2.ToolUsage != BizHawkExternalToolUsage.Global)
/// This event is raised when we add a dll file into {
/// the external tools path. item.ToolTipText = "This tool doesn't work if nothing is loaded";
/// It will automatically load the assembly and add it into the list item.Enabled = false;
/// </summary> }
/// <param name="sender">Object that raised the event</param> else if(attribute2.ToolUsage == BizHawkExternalToolUsage.EmulatorSpecific && Global.Emulator.SystemId != ClientApi.SystemIdConverter.ConvertBack(attribute2.System))
/// <param name="e">Event arguments</param> {
private static void DirectoryMonitor_Created(object sender, FileSystemEventArgs e) item.ToolTipText = "This tool doesn't work for current system";
{ item.Enabled = false;
menuItems.Add(GenerateToolTipFromFileName(e.FullPath)); }
} else if (attribute2.ToolUsage == BizHawkExternalToolUsage.GameSpecific && Global.Game.Hash != attribute2.GameHash)
{
#endregion item.ToolTipText = "This tool doesn't work for current game";
item.Enabled = false;
#region Properties }
}
/// <summary> }
/// Gets a prebuild <see cref="ToolStripMenuItem"/> else
/// This list auto-updated by the <see cref="ExternalToolManager"/> itself {
/// </summary> item = new ToolStripMenuItem(externalToolFile.GetName().Name);
public static IEnumerable<ToolStripMenuItem> ToolStripMenu item.ToolTipText = "BizHawkExternalTool attribute hasn't been found";
{ item.Enabled = false;
get }
{ }
return menuItems; catch (BadImageFormatException)
} {
} item = new ToolStripMenuItem(fileName);
item.ToolTipText = "This is not an assembly";
#endregion item.Enabled = false;
} }
}
#if DEBUG //I added special debug stuff to get additionnal informations. Don(t think it can be usefull for released versions
catch (ReflectionTypeLoadException ex)
{
foreach (Exception e in ex.LoaderExceptions)
{
Debug.WriteLine(e.Message);
}
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#else
catch (ReflectionTypeLoadException)
{
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#endif
return item;
}
/// <summary>
/// This event is raised when we add a dll file into
/// the external tools path.
/// It will automatically load the assembly and add it into the list
/// </summary>
/// <param name="sender">Object that raised the event</param>
/// <param name="e">Event arguments</param>
private static void DirectoryMonitor_Created(object sender, FileSystemEventArgs e)
{
menuItems.Add(GenerateToolTipFromFileName(e.FullPath));
}
#endregion
#region Properties
/// <summary>
/// Gets a prebuild <see cref="ToolStripMenuItem"/>
/// This list auto-updated by the <see cref="ExternalToolManager"/> itself
/// </summary>
public static IEnumerable<ToolStripMenuItem> ToolStripMenu
{
get
{
return menuItems;
}
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,77 +1,77 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// Paint.NET // Paint.NET
// Copyright (C) Rick Brewster, Chris Crosetto, Dennis Dietrich, Tom Jackson, // Copyright (C) Rick Brewster, Chris Crosetto, Dennis Dietrich, Tom Jackson,
// Michael Kelsey, Brandon Ortiz, Craig Taylor, Chris Trevino, // Michael Kelsey, Brandon Ortiz, Craig Taylor, Chris Trevino,
// and Luke Walker // and Luke Walker
// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved.
// See src/setup/License.rtf for complete licensing and attribution information. // See src/setup/License.rtf for complete licensing and attribution information.
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// Copied for Paint.NET PCX Plugin
// Copyright (C) Joshua Bell
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//Bizhawk says: adapted from https://github.com/inexorabletash/PcxFileType/blob/master/Quantize /////////////////////////////////////////////////////////////////////////////////
// Copied for Paint.NET PCX Plugin
// Copyright (C) Joshua Bell
/////////////////////////////////////////////////////////////////////////////////
//Bizhawk says: adapted from https://github.com/inexorabletash/PcxFileType/blob/master/Quantize
using System.Drawing; using System.Drawing;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public sealed class PaletteTable public sealed class PaletteTable
{ {
private Color[] palette; private Color[] palette;
public Color this[int index] public Color this[int index]
{ {
get get
{ {
return this.palette[index]; return this.palette[index];
} }
set set
{ {
this.palette[index] = value; this.palette[index] = value;
} }
} }
private int GetDistanceSquared(Color a, Color b) private int GetDistanceSquared(Color a, Color b)
{ {
int dsq = 0; // delta squared int dsq = 0; // delta squared
int v; int v;
v = a.B - b.B; v = a.B - b.B;
dsq += v * v; dsq += v * v;
v = a.G - b.G; v = a.G - b.G;
dsq += v * v; dsq += v * v;
v = a.R - b.R; v = a.R - b.R;
dsq += v * v; dsq += v * v;
return dsq; return dsq;
} }
public int FindClosestPaletteIndex(Color pixel) public int FindClosestPaletteIndex(Color pixel)
{ {
int dsqBest = int.MaxValue; int dsqBest = int.MaxValue;
int ret = 0; int ret = 0;
for (int i = 0; i < this.palette.Length; ++i) for (int i = 0; i < this.palette.Length; ++i)
{ {
int dsq = GetDistanceSquared(this.palette[i], pixel); int dsq = GetDistanceSquared(this.palette[i], pixel);
if (dsq < dsqBest) if (dsq < dsqBest)
{ {
dsqBest = dsq; dsqBest = dsq;
ret = i; ret = i;
} }
} }
return ret; return ret;
} }
public PaletteTable(Color[] palette) public PaletteTable(Color[] palette)
{ {
this.palette = (Color[])palette.Clone(); this.palette = (Color[])palette.Clone();
} }
} }
} }

View File

@ -1,186 +1,186 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// Paint.NET // Paint.NET
// Copyright (C) Rick Brewster, Chris Crosetto, Dennis Dietrich, Tom Jackson, // Copyright (C) Rick Brewster, Chris Crosetto, Dennis Dietrich, Tom Jackson,
// Michael Kelsey, Brandon Ortiz, Craig Taylor, Chris Trevino, // Michael Kelsey, Brandon Ortiz, Craig Taylor, Chris Trevino,
// and Luke Walker // and Luke Walker
// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved.
// See src/setup/License.rtf for complete licensing and attribution information. // See src/setup/License.rtf for complete licensing and attribution information.
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// Copied for Paint.NET PCX Plugin // Copied for Paint.NET PCX Plugin
// Copyright (C) Joshua Bell // Copyright (C) Joshua Bell
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// Based on: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/colorquant.asp // Based on: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/colorquant.asp
//Bizhawk says: adapted from https://github.com/inexorabletash/PcxFileType/blob/master/Quantize //Bizhawk says: adapted from https://github.com/inexorabletash/PcxFileType/blob/master/Quantize
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
/// <summary> /// <summary>
/// Summary description for Class1. /// Summary description for Class1.
/// </summary> /// </summary>
internal unsafe abstract class Quantizer internal unsafe abstract class Quantizer
{ {
/// <summary> /// <summary>
/// Flag used to indicate whether a single pass or two passes are needed for quantization. /// Flag used to indicate whether a single pass or two passes are needed for quantization.
/// </summary> /// </summary>
private bool _singlePass; private bool _singlePass;
protected bool highquality; protected bool highquality;
public bool HighQuality public bool HighQuality
{ {
get get
{ {
return highquality; return highquality;
} }
set set
{ {
highquality = value; highquality = value;
} }
} }
protected int ditherLevel; protected int ditherLevel;
public int DitherLevel public int DitherLevel
{ {
get get
{ {
return this.ditherLevel; return this.ditherLevel;
} }
set set
{ {
this.ditherLevel = value; this.ditherLevel = value;
} }
} }
/// <summary> /// <summary>
/// Construct the quantizer /// Construct the quantizer
/// </summary> /// </summary>
/// <param name="singlePass">If true, the quantization only needs to loop through the source pixels once</param> /// <param name="singlePass">If true, the quantization only needs to loop through the source pixels once</param>
/// <remarks> /// <remarks>
/// If you construct this class with a true value for singlePass, then the code will, when quantizing your image, /// If you construct this class with a true value for singlePass, then the code will, when quantizing your image,
/// only call the 'QuantizeImage' function. If two passes are required, the code will call 'InitialQuantizeImage' /// only call the 'QuantizeImage' function. If two passes are required, the code will call 'InitialQuantizeImage'
/// and then 'QuantizeImage'. /// and then 'QuantizeImage'.
/// </remarks> /// </remarks>
public Quantizer(bool singlePass) public Quantizer(bool singlePass)
{ {
_singlePass = singlePass; _singlePass = singlePass;
} }
/// <summary> /// <summary>
/// Quantize an image and return the resulting output bitmap /// Quantize an image and return the resulting output bitmap
/// </summary> /// </summary>
/// <param name="source">The image to quantize</param> /// <param name="source">The image to quantize</param>
/// <returns>A quantized version of the image</returns> /// <returns>A quantized version of the image</returns>
public Bitmap Quantize(Image source) public Bitmap Quantize(Image source)
{ {
// Get the size of the source image // Get the size of the source image
int height = source.Height; int height = source.Height;
int width = source.Width; int width = source.Width;
// And construct a rectangle from these dimensions // And construct a rectangle from these dimensions
Rectangle bounds = new Rectangle(0, 0, width, height); Rectangle bounds = new Rectangle(0, 0, width, height);
// First off take a 32bpp copy of the image // First off take a 32bpp copy of the image
Bitmap copy; Bitmap copy;
if (source is Bitmap && source.PixelFormat == PixelFormat.Format32bppArgb) if (source is Bitmap && source.PixelFormat == PixelFormat.Format32bppArgb)
{ {
copy = (Bitmap)source; copy = (Bitmap)source;
} }
else else
{ {
copy = new Bitmap(width, height, PixelFormat.Format32bppArgb); copy = new Bitmap(width, height, PixelFormat.Format32bppArgb);
// Now lock the bitmap into memory // Now lock the bitmap into memory
using (Graphics g = Graphics.FromImage(copy)) using (Graphics g = Graphics.FromImage(copy))
{ {
g.PageUnit = GraphicsUnit.Pixel; g.PageUnit = GraphicsUnit.Pixel;
// Draw the source image onto the copy bitmap, // Draw the source image onto the copy bitmap,
// which will effect a widening as appropriate. // which will effect a widening as appropriate.
g.DrawImage(source, 0, 0, bounds.Width, bounds.Height); g.DrawImage(source, 0, 0, bounds.Width, bounds.Height);
} }
} }
// And construct an 8bpp version // And construct an 8bpp version
Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed); Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
// Define a pointer to the bitmap data // Define a pointer to the bitmap data
BitmapData sourceData = null; BitmapData sourceData = null;
try try
{ {
// Get the source image bits and lock into memory // Get the source image bits and lock into memory
sourceData = copy.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); sourceData = copy.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Call the FirstPass function if not a single pass algorithm. // Call the FirstPass function if not a single pass algorithm.
// For something like an octree quantizer, this will run through // For something like an octree quantizer, this will run through
// all image pixels, build a data structure, and create a palette. // all image pixels, build a data structure, and create a palette.
if (!_singlePass) if (!_singlePass)
{ {
FirstPass(sourceData, width, height); FirstPass(sourceData, width, height);
} }
// Then set the color palette on the output bitmap. I'm passing in the current palette // Then set the color palette on the output bitmap. I'm passing in the current palette
// as there's no way to construct a new, empty palette. // as there's no way to construct a new, empty palette.
output.Palette = this.GetPalette(output.Palette); output.Palette = this.GetPalette(output.Palette);
// Then call the second pass which actually does the conversion // Then call the second pass which actually does the conversion
SecondPass(sourceData, output, width, height, bounds); SecondPass(sourceData, output, width, height, bounds);
} }
finally finally
{ {
// Ensure that the bits are unlocked // Ensure that the bits are unlocked
copy.UnlockBits(sourceData); copy.UnlockBits(sourceData);
} }
if (copy != source) if (copy != source)
{ {
copy.Dispose(); copy.Dispose();
} }
// Last but not least, return the output bitmap // Last but not least, return the output bitmap
return output; return output;
} }
/// <summary> /// <summary>
/// Execute the first pass through the pixels in the image /// Execute the first pass through the pixels in the image
/// </summary> /// </summary>
/// <param name="sourceData">The source data</param> /// <param name="sourceData">The source data</param>
/// <param name="width">The width in pixels of the image</param> /// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param> /// <param name="height">The height in pixels of the image</param>
protected virtual void FirstPass(BitmapData sourceData, int width, int height) protected virtual void FirstPass(BitmapData sourceData, int width, int height)
{ {
// Define the source data pointers. The source row is a byte to // Define the source data pointers. The source row is a byte to
// keep addition of the stride value easier (as this is in bytes) // keep addition of the stride value easier (as this is in bytes)
byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer(); byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer();
int* pSourcePixel; int* pSourcePixel;
// Loop through each row // Loop through each row
for (int row = 0; row < height; row++) for (int row = 0; row < height; row++)
{ {
// Set the source pixel to the first pixel in this row // Set the source pixel to the first pixel in this row
pSourcePixel = (Int32*)pSourceRow; pSourcePixel = (Int32*)pSourceRow;
// And loop through each column // And loop through each column
for (int col = 0; col < width; col++, pSourcePixel++) for (int col = 0; col < width; col++, pSourcePixel++)
{ {
InitialQuantizePixel(*pSourcePixel); InitialQuantizePixel(*pSourcePixel);
} }
// Add the stride to the source row // Add the stride to the source row
pSourceRow += sourceData.Stride; pSourceRow += sourceData.Stride;
} }
} }
int ClampToByte(int val) int ClampToByte(int val)
@ -188,80 +188,80 @@ namespace BizHawk.Client.EmuHawk
if (val < 0) return 0; if (val < 0) return 0;
else if (val > 255) return 255; else if (val > 255) return 255;
else return val; else return val;
} }
/// <summary> /// <summary>
/// Execute a second pass through the bitmap /// Execute a second pass through the bitmap
/// </summary> /// </summary>
/// <param name="sourceData">The source bitmap, locked into memory</param> /// <param name="sourceData">The source bitmap, locked into memory</param>
/// <param name="output">The output bitmap</param> /// <param name="output">The output bitmap</param>
/// <param name="width">The width in pixels of the image</param> /// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param> /// <param name="height">The height in pixels of the image</param>
/// <param name="bounds">The bounding rectangle</param> /// <param name="bounds">The bounding rectangle</param>
protected virtual void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds) protected virtual void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds)
{ {
BitmapData outputData = null; BitmapData outputData = null;
Color[] pallete = output.Palette.Entries; Color[] pallete = output.Palette.Entries;
int weight = ditherLevel; int weight = ditherLevel;
try try
{ {
// Lock the output bitmap into memory // Lock the output bitmap into memory
outputData = output.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); outputData = output.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
// Define the source data pointers. The source row is a byte to // Define the source data pointers. The source row is a byte to
// keep addition of the stride value easier (as this is in bytes) // keep addition of the stride value easier (as this is in bytes)
byte* pSourceRow = (byte *)sourceData.Scan0.ToPointer(); byte* pSourceRow = (byte *)sourceData.Scan0.ToPointer();
Int32* pSourcePixel = (Int32 *)pSourceRow; Int32* pSourcePixel = (Int32 *)pSourceRow;
// Now define the destination data pointers // Now define the destination data pointers
byte* pDestinationRow = (byte *)outputData.Scan0.ToPointer(); byte* pDestinationRow = (byte *)outputData.Scan0.ToPointer();
byte* pDestinationPixel = pDestinationRow; byte* pDestinationPixel = pDestinationRow;
int[] errorThisRowR = new int[width + 1]; int[] errorThisRowR = new int[width + 1];
int[] errorThisRowG = new int[width + 1]; int[] errorThisRowG = new int[width + 1];
int[] errorThisRowB = new int[width + 1]; int[] errorThisRowB = new int[width + 1];
for (int row = 0; row < height; row++) for (int row = 0; row < height; row++)
{ {
int[] errorNextRowR = new int[width + 1]; int[] errorNextRowR = new int[width + 1];
int[] errorNextRowG = new int[width + 1]; int[] errorNextRowG = new int[width + 1];
int[] errorNextRowB = new int[width + 1]; int[] errorNextRowB = new int[width + 1];
int ptrInc; int ptrInc;
if ((row & 1) == 0) if ((row & 1) == 0)
{ {
pSourcePixel = (Int32*)pSourceRow; pSourcePixel = (Int32*)pSourceRow;
pDestinationPixel = pDestinationRow; pDestinationPixel = pDestinationRow;
ptrInc = +1; ptrInc = +1;
} }
else else
{ {
pSourcePixel = (Int32*)pSourceRow + width - 1; pSourcePixel = (Int32*)pSourceRow + width - 1;
pDestinationPixel = pDestinationRow + width - 1; pDestinationPixel = pDestinationRow + width - 1;
ptrInc = -1; ptrInc = -1;
} }
// Loop through each pixel on this scan line // Loop through each pixel on this scan line
for (int col = 0; col < width; ++col) for (int col = 0; col < width; ++col)
{ {
// Quantize the pixel // Quantize the pixel
int srcPixel = *pSourcePixel; int srcPixel = *pSourcePixel;
int srcR = srcPixel & 0xFF; //not int srcR = srcPixel & 0xFF; //not
int srcG = (srcPixel>>8) & 0xFF; //a int srcG = (srcPixel>>8) & 0xFF; //a
int srcB = (srcPixel>>16) & 0xFF; //mistake int srcB = (srcPixel>>16) & 0xFF; //mistake
int srcA = (srcPixel >> 24) & 0xFF; int srcA = (srcPixel >> 24) & 0xFF;
int targetB = ClampToByte(srcB - ((errorThisRowB[col] * weight) / 8)); int targetB = ClampToByte(srcB - ((errorThisRowB[col] * weight) / 8));
int targetG = ClampToByte(srcG - ((errorThisRowG[col] * weight) / 8)); int targetG = ClampToByte(srcG - ((errorThisRowG[col] * weight) / 8));
int targetR = ClampToByte(srcR - ((errorThisRowR[col] * weight) / 8)); int targetR = ClampToByte(srcR - ((errorThisRowR[col] * weight) / 8));
int targetA = srcA; int targetA = srcA;
int target = (targetA<<24)|(targetB<<16)|(targetG<<8)|targetR; int target = (targetA<<24)|(targetB<<16)|(targetG<<8)|targetR;
byte pixelValue = QuantizePixel(target); byte pixelValue = QuantizePixel(target);
*pDestinationPixel = pixelValue; *pDestinationPixel = pixelValue;
int actual = pallete[pixelValue].ToArgb(); int actual = pallete[pixelValue].ToArgb();
@ -269,104 +269,104 @@ namespace BizHawk.Client.EmuHawk
int actualR = actual & 0xFF; int actualR = actual & 0xFF;
int actualG = (actual >> 8) & 0xFF; int actualG = (actual >> 8) & 0xFF;
int actualB = (actual >> 16) & 0xFF; int actualB = (actual >> 16) & 0xFF;
int errorR = actualR - targetR; int errorR = actualR - targetR;
int errorG = actualG - targetG; int errorG = actualG - targetG;
int errorB = actualB - targetB; int errorB = actualB - targetB;
// Floyd-Steinberg Error Diffusion: // Floyd-Steinberg Error Diffusion:
// a) 7/16 error goes to x+1 // a) 7/16 error goes to x+1
// b) 5/16 error goes to y+1 // b) 5/16 error goes to y+1
// c) 3/16 error goes to x-1,y+1 // c) 3/16 error goes to x-1,y+1
// d) 1/16 error goes to x+1,y+1 // d) 1/16 error goes to x+1,y+1
const int a = 7; const int a = 7;
const int b = 5; const int b = 5;
const int c = 3; const int c = 3;
int errorRa = (errorR * a) / 16; int errorRa = (errorR * a) / 16;
int errorRb = (errorR * b) / 16; int errorRb = (errorR * b) / 16;
int errorRc = (errorR * c) / 16; int errorRc = (errorR * c) / 16;
int errorRd = errorR - errorRa - errorRb - errorRc; int errorRd = errorR - errorRa - errorRb - errorRc;
int errorGa = (errorG * a) / 16; int errorGa = (errorG * a) / 16;
int errorGb = (errorG * b) / 16; int errorGb = (errorG * b) / 16;
int errorGc = (errorG * c) / 16; int errorGc = (errorG * c) / 16;
int errorGd = errorG - errorGa - errorGb - errorGc; int errorGd = errorG - errorGa - errorGb - errorGc;
int errorBa = (errorB * a) / 16; int errorBa = (errorB * a) / 16;
int errorBb = (errorB * b) / 16; int errorBb = (errorB * b) / 16;
int errorBc = (errorB * c) / 16; int errorBc = (errorB * c) / 16;
int errorBd = errorB - errorBa - errorBb - errorBc; int errorBd = errorB - errorBa - errorBb - errorBc;
errorThisRowR[col + 1] += errorRa; errorThisRowR[col + 1] += errorRa;
errorThisRowG[col + 1] += errorGa; errorThisRowG[col + 1] += errorGa;
errorThisRowB[col + 1] += errorBa; errorThisRowB[col + 1] += errorBa;
errorNextRowR[width - col] += errorRb; errorNextRowR[width - col] += errorRb;
errorNextRowG[width - col] += errorGb; errorNextRowG[width - col] += errorGb;
errorNextRowB[width - col] += errorBb; errorNextRowB[width - col] += errorBb;
if (col != 0) if (col != 0)
{ {
errorNextRowR[width - (col - 1)] += errorRc; errorNextRowR[width - (col - 1)] += errorRc;
errorNextRowG[width - (col - 1)] += errorGc; errorNextRowG[width - (col - 1)] += errorGc;
errorNextRowB[width - (col - 1)] += errorBc; errorNextRowB[width - (col - 1)] += errorBc;
} }
errorNextRowR[width - (col + 1)] += errorRd; errorNextRowR[width - (col + 1)] += errorRd;
errorNextRowG[width - (col + 1)] += errorGd; errorNextRowG[width - (col + 1)] += errorGd;
errorNextRowB[width - (col + 1)] += errorBd; errorNextRowB[width - (col + 1)] += errorBd;
unchecked unchecked
{ {
pSourcePixel += ptrInc; pSourcePixel += ptrInc;
pDestinationPixel += ptrInc; pDestinationPixel += ptrInc;
} }
} }
// Add the stride to the source row // Add the stride to the source row
pSourceRow += sourceData.Stride; pSourceRow += sourceData.Stride;
// And to the destination row // And to the destination row
pDestinationRow += outputData.Stride; pDestinationRow += outputData.Stride;
errorThisRowB = errorNextRowB; errorThisRowB = errorNextRowB;
errorThisRowG = errorNextRowG; errorThisRowG = errorNextRowG;
errorThisRowR = errorNextRowR; errorThisRowR = errorNextRowR;
} }
} }
finally finally
{ {
// Ensure that I unlock the output bits // Ensure that I unlock the output bits
output.UnlockBits(outputData); output.UnlockBits(outputData);
} }
} }
/// <summary> /// <summary>
/// Override this to process the pixel in the first pass of the algorithm /// Override this to process the pixel in the first pass of the algorithm
/// </summary> /// </summary>
/// <param name="pixel">The pixel to quantize</param> /// <param name="pixel">The pixel to quantize</param>
/// <remarks> /// <remarks>
/// This function need only be overridden if your quantize algorithm needs two passes, /// This function need only be overridden if your quantize algorithm needs two passes,
/// such as an Octree quantizer. /// such as an Octree quantizer.
/// </remarks> /// </remarks>
protected virtual void InitialQuantizePixel(int pixel) protected virtual void InitialQuantizePixel(int pixel)
{ {
} }
/// <summary> /// <summary>
/// Override this to process the pixel in the second pass of the algorithm /// Override this to process the pixel in the second pass of the algorithm
/// </summary> /// </summary>
/// <param name="pixel">The pixel to quantize</param> /// <param name="pixel">The pixel to quantize</param>
/// <returns>The quantized value</returns> /// <returns>The quantized value</returns>
protected abstract byte QuantizePixel(int pixel); protected abstract byte QuantizePixel(int pixel);
/// <summary> /// <summary>
/// Retrieve the palette for the quantized image /// Retrieve the palette for the quantized image
/// </summary> /// </summary>
/// <param name="original">Any old palette, this is overrwritten</param> /// <param name="original">Any old palette, this is overrwritten</param>
/// <returns>The new color palette</returns> /// <returns>The new color palette</returns>
protected abstract ColorPalette GetPalette(ColorPalette original); protected abstract ColorPalette GetPalette(ColorPalette original);
} }
} }

View File

@ -1,21 +1,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class ExceptionBox : Form public partial class ExceptionBox : Form
{ {
public ExceptionBox(Exception ex) public ExceptionBox(Exception ex)
{ {
InitializeComponent(); InitializeComponent();
txtException.Text = ex.ToString(); txtException.Text = ex.ToString();
timer1.Start(); timer1.Start();
} }
public ExceptionBox(string str) public ExceptionBox(string str)
@ -23,70 +23,70 @@ namespace BizHawk.Client.EmuHawk
InitializeComponent(); InitializeComponent();
txtException.Text = str; txtException.Text = str;
timer1.Start(); timer1.Start();
} }
private void btnCopy_Click(object sender, EventArgs e) private void btnCopy_Click(object sender, EventArgs e)
{ {
DoCopy(); DoCopy();
} }
void DoCopy() void DoCopy()
{ {
string txt = txtException.Text; string txt = txtException.Text;
Clipboard.SetText(txt); Clipboard.SetText(txt);
try try
{ {
if (Clipboard.GetText() == txt) if (Clipboard.GetText() == txt)
{ {
lblDone.Text = "Done!"; lblDone.Text = "Done!";
lblDone.ForeColor = SystemColors.ControlText; lblDone.ForeColor = SystemColors.ControlText;
return; return;
} }
} }
catch catch
{ {
} }
lblDone.Text = "ERROR!"; lblDone.Text = "ERROR!";
lblDone.ForeColor = SystemColors.ControlText; lblDone.ForeColor = SystemColors.ControlText;
} }
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{ {
if (keyData == (Keys.C | Keys.Control)) if (keyData == (Keys.C | Keys.Control))
{ {
DoCopy(); DoCopy();
return true; return true;
} }
return false; return false;
} }
private void btnOK_Click(object sender, EventArgs e) private void btnOK_Click(object sender, EventArgs e)
{ {
Close(); Close();
} }
private void timer1_Tick(object sender, EventArgs e) private void timer1_Tick(object sender, EventArgs e)
{ {
int a = lblDone.ForeColor.A - 16; int a = lblDone.ForeColor.A - 16;
if (a < 0) a = 0; if (a < 0) a = 0;
lblDone.ForeColor = Color.FromArgb(a, lblDone.ForeColor); lblDone.ForeColor = Color.FromArgb(a, lblDone.ForeColor);
} }
//http://stackoverflow.com/questions/2636065/alpha-in-forecolor //http://stackoverflow.com/questions/2636065/alpha-in-forecolor
class MyLabel : Label class MyLabel : Label
{ {
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
{ {
Rectangle rc = this.ClientRectangle; Rectangle rc = this.ClientRectangle;
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic); StringFormat fmt = new StringFormat(StringFormat.GenericTypographic);
using (var br = new SolidBrush(this.ForeColor)) using (var br = new SolidBrush(this.ForeColor))
{ {
e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt); e.Graphics.DrawString(this.Text, this.Font, br, rc, fmt);
} }
} }
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +1,351 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Emulation.Cores.Calculators; using BizHawk.Emulation.Cores.Calculators;
using BizHawk.Emulation.Cores.ColecoVision; using BizHawk.Emulation.Cores.ColecoVision;
using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.NES; using BizHawk.Emulation.Cores.Nintendo.NES;
using BizHawk.Emulation.Cores.Nintendo.N64; using BizHawk.Emulation.Cores.Nintendo.N64;
using BizHawk.Emulation.Cores.Nintendo.SNES; using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Cores.PCEngine; using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Cores.Sega.MasterSystem; using BizHawk.Emulation.Cores.Sega.MasterSystem;
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES; using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.CustomControls; using BizHawk.Client.EmuHawk.CustomControls;
using BizHawk.Client.EmuHawk.WinFormExtensions; using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Emulation.Cores.Computers.AppleII; using BizHawk.Emulation.Cores.Computers.AppleII;
using BizHawk.Client.ApiHawk; using BizHawk.Client.ApiHawk;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
partial class MainForm partial class MainForm
{ {
private enum LoadOrdering private enum LoadOrdering
{ {
ROM, ROM,
STATE, STATE,
WATCH, WATCH,
CDLFILE, CDLFILE,
LUASESSION, LUASESSION,
LUASCRIPT, LUASCRIPT,
CHEAT, CHEAT,
MOVIEFILE, MOVIEFILE,
LEGACYMOVIEFILE LEGACYMOVIEFILE
} }
public struct FileInformation public struct FileInformation
{ {
public string directoryName; public string directoryName;
public string fileName; public string fileName;
public string archiveName; public string archiveName;
public FileInformation(string directory, string file, string archive) public FileInformation(string directory, string file, string archive)
{ {
directoryName = directory; directoryName = directory;
fileName = file; fileName = file;
archiveName = archive; archiveName = archive;
} }
} }
// This is the list from MainForm->RomFilter()'s non-developer build. It needs to be kept up-to-date when new cores are added. // This is the list from MainForm->RomFilter()'s non-developer build. It needs to be kept up-to-date when new cores are added.
readonly string[] knownROMExtensions = { ".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC", ".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML", ".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF" }; readonly string[] knownROMExtensions = { ".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC", ".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML", ".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF" };
readonly string[] nonArchive = { ".ISO", ".CUE", ".CCD" }; readonly string[] nonArchive = { ".ISO", ".CUE", ".CCD" };
#region Loaders #region Loaders
// According to the documentation (http://tasvideos.org/Bizhawk/CodeDataLogger.html), // According to the documentation (http://tasvideos.org/Bizhawk/CodeDataLogger.html),
// Currently supported for: PCE, GB/GBC, SMS/GG, Genesis, SNES // Currently supported for: PCE, GB/GBC, SMS/GG, Genesis, SNES
// Perhaps the 'is PCEngine' requirement needs to be expanded. // Perhaps the 'is PCEngine' requirement needs to be expanded.
private void _LoadCDL(string filename, string archive = null) private void _LoadCDL(string filename, string archive = null)
{ {
if (!(Global.Emulator is PCEngine)) if (!(Global.Emulator is PCEngine))
return; return;
GlobalWin.Tools.Load<CDL>(); GlobalWin.Tools.Load<CDL>();
(GlobalWin.Tools.Get<CDL>() as CDL).LoadFile(filename); (GlobalWin.Tools.Get<CDL>() as CDL).LoadFile(filename);
} }
private void _LoadCheats(string filename, string archive = null) private void _LoadCheats(string filename, string archive = null)
{ {
Global.CheatList.Load(filename, false); Global.CheatList.Load(filename, false);
GlobalWin.Tools.Load<Cheats>(); GlobalWin.Tools.Load<Cheats>();
} }
private void _LoadLegacyMovie(string filename, string archive = null) private void _LoadLegacyMovie(string filename, string archive = null)
{ {
if (Global.Emulator.IsNull()) if (Global.Emulator.IsNull())
{ {
OpenRom(); OpenRom();
} }
if (Global.Emulator.IsNull()) if (Global.Emulator.IsNull())
{ {
return; return;
} }
// tries to open a legacy movie format by importing it // tries to open a legacy movie format by importing it
string errorMsg; string errorMsg;
string warningMsg; string warningMsg;
var movie = MovieImport.ImportFile(filename, out errorMsg, out warningMsg); var movie = MovieImport.ImportFile(filename, out errorMsg, out warningMsg);
if (!string.IsNullOrEmpty(errorMsg)) if (!string.IsNullOrEmpty(errorMsg))
{ {
MessageBox.Show(errorMsg, "Conversion error", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(errorMsg, "Conversion error", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
else else
{ {
// fix movie extension to something palatable for these purposes. // fix movie extension to something palatable for these purposes.
// for instance, something which doesnt clobber movies you already may have had. // for instance, something which doesnt clobber movies you already may have had.
// i'm evenly torn between this, and a file in %TEMP%, but since we dont really have a way to clean up this tempfile, i choose this: // i'm evenly torn between this, and a file in %TEMP%, but since we dont really have a way to clean up this tempfile, i choose this:
StartNewMovie(movie, false); StartNewMovie(movie, false);
} }
GlobalWin.OSD.AddMessage(warningMsg); GlobalWin.OSD.AddMessage(warningMsg);
} }
private void _LoadLuaFile(string filename, string archive = null) private void _LoadLuaFile(string filename, string archive = null)
{ {
OpenLuaConsole(); OpenLuaConsole();
if (GlobalWin.Tools.Has<LuaConsole>()) if (GlobalWin.Tools.Has<LuaConsole>())
{ {
GlobalWin.Tools.LuaConsole.LoadLuaFile(filename); GlobalWin.Tools.LuaConsole.LoadLuaFile(filename);
} }
} }
private void _LoadLuaSession(string filename, string archive = null) private void _LoadLuaSession(string filename, string archive = null)
{ {
OpenLuaConsole(); OpenLuaConsole();
if (GlobalWin.Tools.Has<LuaConsole>()) if (GlobalWin.Tools.Has<LuaConsole>())
{ {
GlobalWin.Tools.LuaConsole.LoadLuaSession(filename); GlobalWin.Tools.LuaConsole.LoadLuaSession(filename);
} }
} }
private void _LoadMovie(string filename, string archive = null) private void _LoadMovie(string filename, string archive = null)
{ {
if (Global.Emulator.IsNull()) if (Global.Emulator.IsNull())
{ {
OpenRom(); OpenRom();
} }
if (Global.Emulator.IsNull()) if (Global.Emulator.IsNull())
{ {
return; return;
} }
StartNewMovie(MovieService.Get(filename), false); StartNewMovie(MovieService.Get(filename), false);
} }
private void _LoadRom(string filename, string archive = null) private void _LoadRom(string filename, string archive = null)
{ {
var args = new LoadRomArgs(); var args = new LoadRomArgs();
args.OpenAdvanced = new OpenAdvanced_OpenRom { Path = filename }; args.OpenAdvanced = new OpenAdvanced_OpenRom { Path = filename };
LoadRom(filename, args); LoadRom(filename, args);
} }
private void _LoadState(string filename, string archive = null) private void _LoadState(string filename, string archive = null)
{ {
LoadState(filename, Path.GetFileName(filename)); LoadState(filename, Path.GetFileName(filename));
} }
private void _LoadWatch(string filename, string archive = null) private void _LoadWatch(string filename, string archive = null)
{ {
GlobalWin.Tools.LoadRamWatch(true); GlobalWin.Tools.LoadRamWatch(true);
(GlobalWin.Tools.Get<RamWatch>() as RamWatch).LoadWatchFile(new FileInfo(filename), false); (GlobalWin.Tools.Get<RamWatch>() as RamWatch).LoadWatchFile(new FileInfo(filename), false);
} }
#endregion #endregion
private void ProcessFileList(IEnumerable<string> fileList, ref Dictionary<LoadOrdering, List<FileInformation>> sortedFiles, string archive = null) private void ProcessFileList(IEnumerable<string> fileList, ref Dictionary<LoadOrdering, List<FileInformation>> sortedFiles, string archive = null)
{ {
foreach (string file in fileList) foreach (string file in fileList)
{ {
var ext = Path.GetExtension(file).ToUpper() ?? String.Empty; var ext = Path.GetExtension(file).ToUpper() ?? String.Empty;
FileInformation fileInformation = new FileInformation(Path.GetDirectoryName(file), Path.GetFileName(file), archive); FileInformation fileInformation = new FileInformation(Path.GetDirectoryName(file), Path.GetFileName(file), archive);
switch (ext) switch (ext)
{ {
case ".LUA": case ".LUA":
sortedFiles[LoadOrdering.LUASCRIPT].Add(fileInformation); sortedFiles[LoadOrdering.LUASCRIPT].Add(fileInformation);
break; break;
case ".LUASES": case ".LUASES":
sortedFiles[LoadOrdering.LUASESSION].Add(fileInformation); sortedFiles[LoadOrdering.LUASESSION].Add(fileInformation);
break; break;
case ".STATE": case ".STATE":
sortedFiles[LoadOrdering.STATE].Add(fileInformation); sortedFiles[LoadOrdering.STATE].Add(fileInformation);
break; break;
case ".CHT": case ".CHT":
sortedFiles[LoadOrdering.CHEAT].Add(fileInformation); sortedFiles[LoadOrdering.CHEAT].Add(fileInformation);
break; break;
case ".WCH": case ".WCH":
sortedFiles[LoadOrdering.WATCH].Add(fileInformation); sortedFiles[LoadOrdering.WATCH].Add(fileInformation);
break; break;
case ".CDL": case ".CDL":
sortedFiles[LoadOrdering.CDLFILE].Add(fileInformation); sortedFiles[LoadOrdering.CDLFILE].Add(fileInformation);
break; break;
default: default:
if (MovieService.IsValidMovieExtension(ext)) if (MovieService.IsValidMovieExtension(ext))
sortedFiles[LoadOrdering.MOVIEFILE].Add(fileInformation); sortedFiles[LoadOrdering.MOVIEFILE].Add(fileInformation);
else if (MovieImport.IsValidMovieExtension(ext)) else if (MovieImport.IsValidMovieExtension(ext))
sortedFiles[LoadOrdering.LEGACYMOVIEFILE].Add(fileInformation); sortedFiles[LoadOrdering.LEGACYMOVIEFILE].Add(fileInformation);
else if (knownROMExtensions.Contains(ext)) else if (knownROMExtensions.Contains(ext))
{ {
if (String.IsNullOrEmpty(archive) || !nonArchive.Contains(ext)) if (String.IsNullOrEmpty(archive) || !nonArchive.Contains(ext))
sortedFiles[LoadOrdering.ROM].Add(fileInformation); sortedFiles[LoadOrdering.ROM].Add(fileInformation);
} }
else else
{ {
/* Because the existing behaviour for archives is to try loading /* Because the existing behaviour for archives is to try loading
* ROMs out of them, that is exactly what we are going to continue * ROMs out of them, that is exactly what we are going to continue
* to do at present. Ideally, the archive should be scanned and * to do at present. Ideally, the archive should be scanned and
* relevant files should be extracted, but see the note below for * relevant files should be extracted, but see the note below for
* further details. * further details.
*/ */
int offset = 0; int offset = 0;
bool executable = false; bool executable = false;
var archiveHandler = new SevenZipSharpArchiveHandler(); var archiveHandler = new SevenZipSharpArchiveHandler();
if (String.IsNullOrEmpty(archive) && archiveHandler.CheckSignature(file, out offset, out executable)) if (String.IsNullOrEmpty(archive) && archiveHandler.CheckSignature(file, out offset, out executable))
sortedFiles[LoadOrdering.ROM].Add(fileInformation); sortedFiles[LoadOrdering.ROM].Add(fileInformation);
/* /*
* This is where handling archives would go. * This is where handling archives would go.
* Right now, that's going to be a HUGE hassle, because of the problem with * Right now, that's going to be a HUGE hassle, because of the problem with
* saving things into the archive (no) and with everything requiring filenames * saving things into the archive (no) and with everything requiring filenames
* and not streams (also no), so for the purposes of making drag/drop more robust, * and not streams (also no), so for the purposes of making drag/drop more robust,
* I am not building this out just yet. * I am not building this out just yet.
* -- Adam Michaud (Invariel) * -- Adam Michaud (Invariel)
int offset = 0; int offset = 0;
bool executable = false; bool executable = false;
var archiveHandler = new SevenZipSharpArchiveHandler(); var archiveHandler = new SevenZipSharpArchiveHandler();
// Not going to process nested archives at the moment. // Not going to process nested archives at the moment.
if (String.IsNullOrEmpty (archive) && archiveHandler.CheckSignature(file, out offset, out executable)) if (String.IsNullOrEmpty (archive) && archiveHandler.CheckSignature(file, out offset, out executable))
{ {
List<string> fileNames = new List<string>(); List<string> fileNames = new List<string>();
var openedArchive = archiveHandler.Construct (file); var openedArchive = archiveHandler.Construct (file);
foreach (BizHawk.Common.HawkFileArchiveItem item in openedArchive.Scan ()) foreach (BizHawk.Common.HawkFileArchiveItem item in openedArchive.Scan ())
fileNames.Add(item.Name); fileNames.Add(item.Name);
ProcessFileList(fileNames.ToArray(), ref sortedFiles, file); ProcessFileList(fileNames.ToArray(), ref sortedFiles, file);
openedArchive.Dispose(); openedArchive.Dispose();
} }
archiveHandler.Dispose(); archiveHandler.Dispose();
*/ */
} }
break; break;
} }
} }
} }
private void _FormDragDrop_internal(object sender, DragEventArgs e) private void _FormDragDrop_internal(object sender, DragEventArgs e)
{ {
/* /*
* Refactor, moving the loading of particular files into separate functions that can * Refactor, moving the loading of particular files into separate functions that can
* then be used by this code, and loading individual files through the file dialogue. * then be used by this code, and loading individual files through the file dialogue.
* *
* Step 1: * Step 1:
* Build a dictionary of relevant files from everything that was dragged and dropped. * Build a dictionary of relevant files from everything that was dragged and dropped.
* This includes peeking into all relevant archives and using their files. * This includes peeking into all relevant archives and using their files.
* *
* Step 2: * Step 2:
* Perhaps ask the user which of a particular file type they want to use. * Perhaps ask the user which of a particular file type they want to use.
* Example: rom1.nes, rom2.smc, rom3.cue are drag-dropped, ask the user which they want to use. * Example: rom1.nes, rom2.smc, rom3.cue are drag-dropped, ask the user which they want to use.
* *
* Step 3: * Step 3:
* Load all of the relevant files, in priority order: * Load all of the relevant files, in priority order:
* 1) The ROM * 1) The ROM
* 2) State * 2) State
* 3) Watch files * 3) Watch files
* 4) Code Data Logger (CDL) * 4) Code Data Logger (CDL)
* 5) LUA sessions * 5) LUA sessions
* 6) LUA scripts * 6) LUA scripts
* 7) Cheat files * 7) Cheat files
* 8) Movie Playback Files * 8) Movie Playback Files
* *
* Bonus: * Bonus:
* Make that order easy to change in the code, heavily suggesting ROM and playback as first and last respectively. * Make that order easy to change in the code, heavily suggesting ROM and playback as first and last respectively.
*/ */
var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop); var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop);
Dictionary<LoadOrdering, List<FileInformation>> sortedFiles = new Dictionary<LoadOrdering, List<FileInformation>>(); Dictionary<LoadOrdering, List<FileInformation>> sortedFiles = new Dictionary<LoadOrdering, List<FileInformation>>();
// Initialize the dictionary's lists. // Initialize the dictionary's lists.
foreach (LoadOrdering value in Enum.GetValues(typeof(LoadOrdering))) foreach (LoadOrdering value in Enum.GetValues(typeof(LoadOrdering)))
{ {
sortedFiles.Add(value, new List<FileInformation>()); sortedFiles.Add(value, new List<FileInformation>());
} }
ProcessFileList(HawkFile.Util_ResolveLinks(filePaths), ref sortedFiles, null); ProcessFileList(HawkFile.Util_ResolveLinks(filePaths), ref sortedFiles, null);
// For each of the different types of item, if there are no items of that type, skip them. // For each of the different types of item, if there are no items of that type, skip them.
// If there is exactly one of that type of item, load it. // If there is exactly one of that type of item, load it.
// If there is more than one, ask. // If there is more than one, ask.
foreach (LoadOrdering value in Enum.GetValues(typeof(LoadOrdering))) foreach (LoadOrdering value in Enum.GetValues(typeof(LoadOrdering)))
{ {
switch (sortedFiles[value].Count) switch (sortedFiles[value].Count)
{ {
case 0: case 0:
break; break;
case 1: case 1:
FileInformation fileInformation = sortedFiles[value].First<FileInformation>(); FileInformation fileInformation = sortedFiles[value].First<FileInformation>();
string filename = Path.Combine(new string[] { fileInformation.directoryName, fileInformation.fileName }); string filename = Path.Combine(new string[] { fileInformation.directoryName, fileInformation.fileName });
switch (value) switch (value)
{ {
case LoadOrdering.ROM: case LoadOrdering.ROM:
_LoadRom(filename, fileInformation.archiveName); _LoadRom(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.STATE: case LoadOrdering.STATE:
_LoadState(filename, fileInformation.archiveName); _LoadState(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.WATCH: case LoadOrdering.WATCH:
_LoadWatch(filename, fileInformation.archiveName); _LoadWatch(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.CDLFILE: case LoadOrdering.CDLFILE:
_LoadCDL(filename, fileInformation.archiveName); _LoadCDL(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.LUASESSION: case LoadOrdering.LUASESSION:
_LoadLuaSession(filename, fileInformation.archiveName); _LoadLuaSession(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.LUASCRIPT: case LoadOrdering.LUASCRIPT:
_LoadLuaFile(filename, fileInformation.archiveName); _LoadLuaFile(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.CHEAT: case LoadOrdering.CHEAT:
_LoadCheats(filename, fileInformation.archiveName); _LoadCheats(filename, fileInformation.archiveName);
break; break;
case LoadOrdering.MOVIEFILE: case LoadOrdering.MOVIEFILE:
case LoadOrdering.LEGACYMOVIEFILE: case LoadOrdering.LEGACYMOVIEFILE:
// I don't really like this hack, but for now, we only want to load one movie file. // I don't really like this hack, but for now, we only want to load one movie file.
if (sortedFiles[LoadOrdering.MOVIEFILE].Count + sortedFiles[LoadOrdering.LEGACYMOVIEFILE].Count > 1) if (sortedFiles[LoadOrdering.MOVIEFILE].Count + sortedFiles[LoadOrdering.LEGACYMOVIEFILE].Count > 1)
break; break;
if (value == LoadOrdering.MOVIEFILE) if (value == LoadOrdering.MOVIEFILE)
_LoadMovie(filename, fileInformation.archiveName); _LoadMovie(filename, fileInformation.archiveName);
else else
_LoadLegacyMovie(filename, fileInformation.archiveName); _LoadLegacyMovie(filename, fileInformation.archiveName);
break; break;
} }
break; break;
default: default:
break; break;
} }
} }
} }
} }
} }

View File

@ -1,32 +1,32 @@
using System; using System;
using BizHawk.Bizware.BizwareGL; using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
/// <summary> /// <summary>
/// This singleton class manages OpenGL contexts, in an effort to minimize context changes. /// This singleton class manages OpenGL contexts, in an effort to minimize context changes.
/// </summary> /// </summary>
public class GLManager : IDisposable public class GLManager : IDisposable
{ {
private GLManager() private GLManager()
{ {
} }
public void Dispose() public void Dispose()
{ {
} }
public static GLManager Instance { get; private set; } public static GLManager Instance { get; private set; }
Bizware.BizwareGL.Drivers.OpenTK.IGL_TK MainContext; Bizware.BizwareGL.Drivers.OpenTK.IGL_TK MainContext;
public static void CreateInstance(Bizware.BizwareGL.Drivers.OpenTK.IGL_TK mainContext) public static void CreateInstance(Bizware.BizwareGL.Drivers.OpenTK.IGL_TK mainContext)
{ {
if (Instance != null) throw new InvalidOperationException("Attempt to create more than one GLManager"); if (Instance != null) throw new InvalidOperationException("Attempt to create more than one GLManager");
Instance = new GLManager(); Instance = new GLManager();
Instance.MainContext = mainContext; Instance.MainContext = mainContext;
} }
public void ReleaseGLContext(object o) public void ReleaseGLContext(object o)
@ -38,77 +38,77 @@ namespace BizHawk.Client.EmuHawk
//[System.Runtime.InteropServices.DllImport("opengl32.dll")] //[System.Runtime.InteropServices.DllImport("opengl32.dll")]
//bool wglShareLists(IntPtr hglrc1, IntPtr hglrc2); //bool wglShareLists(IntPtr hglrc1, IntPtr hglrc2);
public ContextRef CreateGLContext(int major_version, int minor_version, bool forward_compatible) public ContextRef CreateGLContext(int major_version, int minor_version, bool forward_compatible)
{ {
var gl = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(major_version, minor_version, forward_compatible); var gl = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(major_version, minor_version, forward_compatible);
var ret = new ContextRef { gl = gl }; var ret = new ContextRef { gl = gl };
return ret; return ret;
} }
public ContextRef GetContextForGraphicsControl(GraphicsControl gc) public ContextRef GetContextForGraphicsControl(GraphicsControl gc)
{ {
return new ContextRef return new ContextRef
{ {
gc = gc, gc = gc,
gl = gc.IGL gl = gc.IGL
}; };
} }
/// <summary> /// <summary>
/// This might not be a GL implementation. If it isnt GL, then setting it as active context is just NOP /// This might not be a GL implementation. If it isnt GL, then setting it as active context is just NOP
/// </summary> /// </summary>
public ContextRef GetContextForIGL(IGL gl) public ContextRef GetContextForIGL(IGL gl)
{ {
return new ContextRef return new ContextRef
{ {
gl = gl gl = gl
}; };
} }
ContextRef ActiveContext; ContextRef ActiveContext;
public void Invalidate() public void Invalidate()
{ {
ActiveContext = null; ActiveContext = null;
} }
public void Activate(ContextRef cr) public void Activate(ContextRef cr)
{ {
bool begun = false; bool begun = false;
//this needs a begin signal to set the swap chain to the next backbuffer //this needs a begin signal to set the swap chain to the next backbuffer
if (cr.gl is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9) if (cr.gl is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
{ {
cr.gc.Begin(); cr.gc.Begin();
begun = true; begun = true;
} }
if (cr == ActiveContext) if (cr == ActiveContext)
return; return;
ActiveContext = cr; ActiveContext = cr;
if (cr.gc != null) if (cr.gc != null)
{ {
//TODO - this is checking the current context inside to avoid an extra NOP context change. make this optional or remove it, since we're tracking it here //TODO - this is checking the current context inside to avoid an extra NOP context change. make this optional or remove it, since we're tracking it here
if(!begun) if(!begun)
cr.gc.Begin(); cr.gc.Begin();
} }
else if (cr.gl != null) else if (cr.gl != null)
{ {
if(cr.gl is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK) if(cr.gl is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)
((BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)cr.gl).MakeDefaultCurrent(); ((BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)cr.gl).MakeDefaultCurrent();
} }
} }
public void Deactivate() public void Deactivate()
{ {
//this is here for future use and tracking purposes.. however.. instead of relying on this, we should just make sure we always activate what we need before we use it //this is here for future use and tracking purposes.. however.. instead of relying on this, we should just make sure we always activate what we need before we use it
} }
public class ContextRef public class ContextRef
{ {
public IGL gl; public IGL gl;
public GraphicsControl gc; public GraphicsControl gc;
} }
} }
} }

View File

@ -1,43 +1,43 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Cores.Sony.PSX; using BizHawk.Emulation.Cores.Sony.PSX;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.WinFormExtensions; using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Common.ReflectionExtensions; using BizHawk.Common.ReflectionExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class PSXControllerConfigNew : Form public partial class PSXControllerConfigNew : Form
{ {
public PSXControllerConfigNew() public PSXControllerConfigNew()
{ {
InitializeComponent(); InitializeComponent();
} }
private void PSXControllerConfigNew_Load(object sender, EventArgs e) private void PSXControllerConfigNew_Load(object sender, EventArgs e)
{ {
//populate combo boxes //populate combo boxes
foreach(var combo in new[]{combo_1_1,combo_1_2,combo_1_3,combo_1_4,combo_2_1,combo_2_2,combo_2_3,combo_2_4}) foreach(var combo in new[]{combo_1_1,combo_1_2,combo_1_3,combo_1_4,combo_2_1,combo_2_2,combo_2_3,combo_2_4})
{ {
combo.Items.Add("-Nothing-"); combo.Items.Add("-Nothing-");
combo.Items.Add("Gamepad"); combo.Items.Add("Gamepad");
combo.Items.Add("Dual Shock"); combo.Items.Add("Dual Shock");
combo.Items.Add("Dual Analog"); combo.Items.Add("Dual Analog");
combo.SelectedIndex = 0; combo.SelectedIndex = 0;
} }
var psxSettings = ((Octoshock)Global.Emulator).GetSyncSettings(); var psxSettings = ((Octoshock)Global.Emulator).GetSyncSettings();
GuiFromUserConfig(psxSettings.FIOConfig); GuiFromUserConfig(psxSettings.FIOConfig);
RefreshLabels(); RefreshLabels();
} }
void GuiFromUserConfig(OctoshockFIOConfigUser user) void GuiFromUserConfig(OctoshockFIOConfigUser user)
@ -56,7 +56,7 @@ namespace BizHawk.Client.EmuHawk
if (user.Devices8[i] == OctoshockDll.ePeripheralType.DualShock) combo.SelectedIndex = 2; if (user.Devices8[i] == OctoshockDll.ePeripheralType.DualShock) combo.SelectedIndex = 2;
if (user.Devices8[i] == OctoshockDll.ePeripheralType.DualAnalog) combo.SelectedIndex = 3; if (user.Devices8[i] == OctoshockDll.ePeripheralType.DualAnalog) combo.SelectedIndex = 3;
} }
} }
OctoshockFIOConfigUser UserConfigFromGui() OctoshockFIOConfigUser UserConfigFromGui()
{ {
@ -79,60 +79,60 @@ namespace BizHawk.Client.EmuHawk
} }
return uc; return uc;
} }
void RefreshLabels() void RefreshLabels()
{ {
var uc = UserConfigFromGui(); var uc = UserConfigFromGui();
bool b1 = uc.Multitaps[0]; bool b1 = uc.Multitaps[0];
lbl_1_1.Visible = b1; lbl_1_1.Visible = b1;
lbl_1_2.Visible = b1; lbl_1_2.Visible = b1;
lbl_1_3.Visible = b1; lbl_1_3.Visible = b1;
lbl_1_4.Visible = b1; lbl_1_4.Visible = b1;
combo_1_2.Enabled = b1; combo_1_2.Enabled = b1;
combo_1_3.Enabled = b1; combo_1_3.Enabled = b1;
combo_1_4.Enabled = b1; combo_1_4.Enabled = b1;
lbl_p_1_2.Visible = b1; lbl_p_1_2.Visible = b1;
lbl_p_1_3.Visible = b1; lbl_p_1_3.Visible = b1;
lbl_p_1_4.Visible = b1; lbl_p_1_4.Visible = b1;
bool b2 = uc.Multitaps[1]; bool b2 = uc.Multitaps[1];
lbl_2_1.Visible = b2; lbl_2_1.Visible = b2;
lbl_2_2.Visible = b2; lbl_2_2.Visible = b2;
lbl_2_3.Visible = b2; lbl_2_3.Visible = b2;
lbl_2_4.Visible = b2; lbl_2_4.Visible = b2;
combo_2_2.Enabled = b2; combo_2_2.Enabled = b2;
combo_2_3.Enabled = b2; combo_2_3.Enabled = b2;
combo_2_4.Enabled = b2; combo_2_4.Enabled = b2;
lbl_p_2_2.Visible = b2; lbl_p_2_2.Visible = b2;
lbl_p_2_3.Visible = b2; lbl_p_2_3.Visible = b2;
lbl_p_2_4.Visible = b2; lbl_p_2_4.Visible = b2;
var LC = uc.ToLogical(); var LC = uc.ToLogical();
var p_labels = new[] { lbl_p_1_1,lbl_p_1_2,lbl_p_1_3,lbl_p_1_4,lbl_p_2_1,lbl_p_2_2,lbl_p_2_3,lbl_p_2_4}; var p_labels = new[] { lbl_p_1_1,lbl_p_1_2,lbl_p_1_3,lbl_p_1_4,lbl_p_2_1,lbl_p_2_2,lbl_p_2_3,lbl_p_2_4};
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
var lbl = p_labels[i]; var lbl = p_labels[i];
if (LC.PlayerAssignments[i] == -1) if (LC.PlayerAssignments[i] == -1)
lbl.Visible = false; lbl.Visible = false;
else else
{ {
lbl.Text = "P" + LC.PlayerAssignments[i]; lbl.Text = "P" + LC.PlayerAssignments[i];
lbl.Visible = true; lbl.Visible = true;
} }
} }
} }
private void cb_changed(object sender, EventArgs e) private void cb_changed(object sender, EventArgs e)
{ {
RefreshLabels(); RefreshLabels();
} }
private void combo_SelectedIndexChanged(object sender, EventArgs e) private void combo_SelectedIndexChanged(object sender, EventArgs e)
{ {
RefreshLabels(); RefreshLabels();
} }
private void btnOK_Click(object sender, EventArgs e) private void btnOK_Click(object sender, EventArgs e)
@ -145,6 +145,6 @@ namespace BizHawk.Client.EmuHawk
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
Close(); Close();
} }
} }
} }

View File

@ -1,188 +1,188 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
//TODO - select which memorydomains go out to the CDL file. will this cause a problem when re-importing it? //TODO - select which memorydomains go out to the CDL file. will this cause a problem when re-importing it?
//perhaps missing domains shouldnt fail a check //perhaps missing domains shouldnt fail a check
//OR - just add a contextmenu option to the listview item that selects it for export. //OR - just add a contextmenu option to the listview item that selects it for export.
//TODO - add a contextmenu option which warps to the hexeditor with the provided domain selected for visualizing on the hex editor. //TODO - add a contextmenu option which warps to the hexeditor with the provided domain selected for visualizing on the hex editor.
//TODO - consider setting colors for columns in CDL //TODO - consider setting colors for columns in CDL
//TODO - option to print domain name in caption instead of 0x01 etc. //TODO - option to print domain name in caption instead of 0x01 etc.
//TODO - context menu should have copy option too //TODO - context menu should have copy option too
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class CDL : ToolFormBase, IToolFormAutoConfig public partial class CDL : ToolFormBase, IToolFormAutoConfig
{ {
private RecentFiles _recent_fld = new RecentFiles(); private RecentFiles _recent_fld = new RecentFiles();
[ConfigPersist] [ConfigPersist]
private RecentFiles _recent private RecentFiles _recent
{ {
get get
{ return _recent_fld; } { return _recent_fld; }
set set
{ {
_recent_fld = value; _recent_fld = value;
if (_recent_fld.AutoLoad) if (_recent_fld.AutoLoad)
{ {
LoadFile(_recent.MostRecent); LoadFile(_recent.MostRecent);
SetCurrentFilename(_recent.MostRecent); SetCurrentFilename(_recent.MostRecent);
} }
} }
}
void SetCurrentFilename(string fname)
{
_currentFilename = fname;
if (_currentFilename == null)
Text = "Code Data Logger";
else Text = string.Format("Code Data Logger - {0}", fname);
}
[RequiredService]
private IMemoryDomains MemoryDomains { get; set; }
[RequiredService]
private ICodeDataLogger CodeDataLogger { get; set; }
private string _currentFilename = null;
private CodeDataLog _cdl;
public CDL()
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
InitializeComponent();
tsbViewStyle.SelectedIndex = 0;
} }
public void NewUpdate(ToolFormUpdateType type) { } void SetCurrentFilename(string fname)
{
public void UpdateValues() _currentFilename = fname;
{ if (_currentFilename == null)
UpdateDisplay(false); Text = "Code Data Logger";
} else Text = string.Format("Code Data Logger - {0}", fname);
}
public void FastUpdate()
{ [RequiredService]
// Do nothing private IMemoryDomains MemoryDomains { get; set; }
}
[RequiredService]
public void Restart() private ICodeDataLogger CodeDataLogger { get; set; }
{
//don't try to recover the current CDL! private string _currentFilename = null;
//even though it seems like it might be nice, it might get mixed up between games. even if we use CheckCDL. Switching games with the same memory map will be bad. private CodeDataLog _cdl;
_cdl = null;
SetCurrentFilename(null); public CDL()
SetLoggingActiveCheck(false); {
UpdateDisplay(true); SetStyle(ControlStyles.AllPaintingInWmPaint, true);
} SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
void SetLoggingActiveCheck(bool value) InitializeComponent();
{
tsbLoggingActive.Checked = value; tsbViewStyle.SelectedIndex = 0;
} }
string[][] listContents = new string[0][]; public void NewUpdate(ToolFormUpdateType type) { }
private void UpdateDisplay(bool force) public void UpdateValues()
{ {
if (!tsbViewUpdate.Checked && !force) UpdateDisplay(false);
return; }
public void FastUpdate()
if (_cdl == null) {
{ // Do nothing
lvCDL.BeginUpdate(); }
lvCDL.Items.Clear();
lvCDL.EndUpdate(); public void Restart()
return; {
} //don't try to recover the current CDL!
//even though it seems like it might be nice, it might get mixed up between games. even if we use CheckCDL. Switching games with the same memory map will be bad.
lvCDL.BeginUpdate(); _cdl = null;
SetCurrentFilename(null);
listContents = new string[_cdl.Count][]; SetLoggingActiveCheck(false);
UpdateDisplay(true);
int idx = 0; }
foreach (var kvp in _cdl)
{ void SetLoggingActiveCheck(bool value)
int[] totals = new int[8]; {
int total = 0; tsbLoggingActive.Checked = value;
unsafe }
{
int* map = stackalloc int[256]; string[][] listContents = new string[0][];
for (int i = 0; i < 256; i++)
map[i] = 0; private void UpdateDisplay(bool force)
{
fixed (byte* data = kvp.Value) if (!tsbViewUpdate.Checked && !force)
{ return;
byte* src = data;
byte* end = data + kvp.Value.Length;
while (src < end) if (_cdl == null)
{ {
byte s = *src++; lvCDL.BeginUpdate();
map[s]++; lvCDL.Items.Clear();
} lvCDL.EndUpdate();
} return;
}
for (int i = 0; i < 256; i++)
{ lvCDL.BeginUpdate();
if(i!=0) total += map[i];
if ((i & 0x01) != 0) totals[0] += map[i]; listContents = new string[_cdl.Count][];
if ((i & 0x02) != 0) totals[1] += map[i];
if ((i & 0x04) != 0) totals[2] += map[i]; int idx = 0;
if ((i & 0x08) != 0) totals[3] += map[i]; foreach (var kvp in _cdl)
if ((i & 0x10) != 0) totals[4] += map[i]; {
if ((i & 0x20) != 0) totals[5] += map[i]; int[] totals = new int[8];
if ((i & 0x40) != 0) totals[6] += map[i]; int total = 0;
if ((i & 0x80) != 0) totals[7] += map[i]; unsafe
} {
} int* map = stackalloc int[256];
for (int i = 0; i < 256; i++)
var bm = _cdl.GetBlockMap(); map[i] = 0;
long addr = bm[kvp.Key];
fixed (byte* data = kvp.Value)
var lvi = listContents[idx++] = new string[13]; {
lvi[0] = string.Format("{0:X8}", addr); byte* src = data;
lvi[1] = kvp.Key; byte* end = data + kvp.Value.Length;
lvi[2] = string.Format("{0:0.00}%", total / (float)kvp.Value.Length * 100f); while (src < end)
if (tsbViewStyle.SelectedIndex == 2) {
lvi[3] = string.Format("{0:0.00}", total / 1024.0f); byte s = *src++;
else map[s]++;
lvi[3] = string.Format("{0}", total); }
if (tsbViewStyle.SelectedIndex == 2) }
{
int n = (int)(kvp.Value.Length / 1024.0f); for (int i = 0; i < 256; i++)
float ncheck = kvp.Value.Length / 1024.0f; {
lvi[4] = string.Format("of {0}{1} KBytes", n == ncheck ? "" : "~", n); if(i!=0) total += map[i];
} if ((i & 0x01) != 0) totals[0] += map[i];
else if ((i & 0x02) != 0) totals[1] += map[i];
lvi[4] = string.Format("of {0} Bytes", kvp.Value.Length); if ((i & 0x04) != 0) totals[2] += map[i];
for (int i = 0; i < 8; i++) if ((i & 0x08) != 0) totals[3] += map[i];
{ if ((i & 0x10) != 0) totals[4] += map[i];
if (tsbViewStyle.SelectedIndex == 0) if ((i & 0x20) != 0) totals[5] += map[i];
lvi[5 + i] = string.Format("{0:0.00}%", totals[i] / (float)kvp.Value.Length * 100f); if ((i & 0x40) != 0) totals[6] += map[i];
if (tsbViewStyle.SelectedIndex == 1) if ((i & 0x80) != 0) totals[7] += map[i];
lvi[5 + i] = string.Format("{0}", totals[i]); }
if (tsbViewStyle.SelectedIndex == 2) }
lvi[5 + i] = string.Format("{0:0.00}", totals[i] / 1024.0f);
} var bm = _cdl.GetBlockMap();
long addr = bm[kvp.Key];
}
lvCDL.VirtualListSize = _cdl.Count; var lvi = listContents[idx++] = new string[13];
lvCDL.EndUpdate(); lvi[0] = string.Format("{0:X8}", addr);
} lvi[1] = kvp.Key;
lvi[2] = string.Format("{0:0.00}%", total / (float)kvp.Value.Length * 100f);
public bool AskSaveChanges() if (tsbViewStyle.SelectedIndex == 2)
lvi[3] = string.Format("{0:0.00}", total / 1024.0f);
else
lvi[3] = string.Format("{0}", total);
if (tsbViewStyle.SelectedIndex == 2)
{
int n = (int)(kvp.Value.Length / 1024.0f);
float ncheck = kvp.Value.Length / 1024.0f;
lvi[4] = string.Format("of {0}{1} KBytes", n == ncheck ? "" : "~", n);
}
else
lvi[4] = string.Format("of {0} Bytes", kvp.Value.Length);
for (int i = 0; i < 8; i++)
{
if (tsbViewStyle.SelectedIndex == 0)
lvi[5 + i] = string.Format("{0:0.00}%", totals[i] / (float)kvp.Value.Length * 100f);
if (tsbViewStyle.SelectedIndex == 1)
lvi[5 + i] = string.Format("{0}", totals[i]);
if (tsbViewStyle.SelectedIndex == 2)
lvi[5 + i] = string.Format("{0:0.00}", totals[i] / 1024.0f);
}
}
lvCDL.VirtualListSize = _cdl.Count;
lvCDL.EndUpdate();
}
public bool AskSaveChanges()
{ {
//nothing to fear: //nothing to fear:
if (_cdl == null) if (_cdl == null)
@ -208,108 +208,108 @@ namespace BizHawk.Client.EmuHawk
} }
} }
return true; return true;
} }
public bool UpdateBefore public bool UpdateBefore
{ {
get { return false; } get { return false; }
} }
public void LoadFile(string path) public void LoadFile(string path)
{ {
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{ {
var newCDL = new CodeDataLog(); var newCDL = new CodeDataLog();
newCDL.Load(fs); newCDL.Load(fs);
//have the core create a CodeDataLog to check mapping information against //have the core create a CodeDataLog to check mapping information against
var testCDL = new CodeDataLog(); var testCDL = new CodeDataLog();
CodeDataLogger.NewCDL(testCDL); CodeDataLogger.NewCDL(testCDL);
if (!newCDL.Check(testCDL)) if (!newCDL.Check(testCDL))
{ {
MessageBox.Show(this, "CDL file does not match emulator's current memory map!"); MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return; return;
} }
//ok, it's all good: //ok, it's all good:
_cdl = newCDL; _cdl = newCDL;
CodeDataLogger.SetCDL(null); CodeDataLogger.SetCDL(null);
if (tsbLoggingActive.Checked || Global.Config.CDLAutoStart) if (tsbLoggingActive.Checked || Global.Config.CDLAutoStart)
CodeDataLogger.SetCDL(_cdl); CodeDataLogger.SetCDL(_cdl);
SetCurrentFilename(path); SetCurrentFilename(path);
} }
UpdateDisplay(true); UpdateDisplay(true);
} }
private void FileSubMenu_DropDownOpened(object sender, EventArgs e) private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
{ {
SaveMenuItem.Enabled = _currentFilename != null; SaveMenuItem.Enabled = _currentFilename != null;
SaveAsMenuItem.Enabled = SaveAsMenuItem.Enabled =
AppendMenuItem.Enabled = AppendMenuItem.Enabled =
ClearMenuItem.Enabled = ClearMenuItem.Enabled =
DisassembleMenuItem.Enabled = DisassembleMenuItem.Enabled =
_cdl != null; _cdl != null;
miAutoSave.Checked = Global.Config.CDLAutoSave; miAutoSave.Checked = Global.Config.CDLAutoSave;
miAutoStart.Checked = Global.Config.CDLAutoStart; miAutoStart.Checked = Global.Config.CDLAutoStart;
}
private void RecentSubMenu_DropDownOpened(object sender, EventArgs e)
{
RecentSubMenu.DropDownItems.Clear();
RecentSubMenu.DropDownItems.AddRange(_recent.RecentMenu(LoadFile, true));
} }
void NewFileLogic() private void RecentSubMenu_DropDownOpened(object sender, EventArgs e)
{ {
_cdl = new CodeDataLog(); RecentSubMenu.DropDownItems.Clear();
CodeDataLogger.NewCDL(_cdl); RecentSubMenu.DropDownItems.AddRange(_recent.RecentMenu(LoadFile, true));
}
if (tsbLoggingActive.Checked || Global.Config.CDLAutoStart)
CodeDataLogger.SetCDL(_cdl); void NewFileLogic()
else CodeDataLogger.SetCDL(null); {
_cdl = new CodeDataLog();
SetCurrentFilename(null); CodeDataLogger.NewCDL(_cdl);
UpdateDisplay(true); if (tsbLoggingActive.Checked || Global.Config.CDLAutoStart)
} CodeDataLogger.SetCDL(_cdl);
else CodeDataLogger.SetCDL(null);
private void NewMenuItem_Click(object sender, EventArgs e)
{ SetCurrentFilename(null);
//take care not to clobber an existing CDL
if (_cdl != null) UpdateDisplay(true);
{ }
var result = MessageBox.Show(this, "OK to create new CDL?", "Query", MessageBoxButtons.YesNo);
if (result != DialogResult.Yes) private void NewMenuItem_Click(object sender, EventArgs e)
return; {
} //take care not to clobber an existing CDL
if (_cdl != null)
NewFileLogic(); {
} var result = MessageBox.Show(this, "OK to create new CDL?", "Query", MessageBoxButtons.YesNo);
if (result != DialogResult.Yes)
private void OpenMenuItem_Click(object sender, EventArgs e) return;
{ }
var file = OpenFileDialog(
_currentFilename, NewFileLogic();
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), }
"Code Data Logger Files",
"cdl"); private void OpenMenuItem_Click(object sender, EventArgs e)
{
if (file == null) var file = OpenFileDialog(
return; _currentFilename,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null),
//take care not to clobber an existing CDL "Code Data Logger Files",
if (_cdl != null) "cdl");
{
var result = MessageBox.Show(this, "OK to load new CDL?", "Query", MessageBoxButtons.YesNo); if (file == null)
if (result != DialogResult.Yes) return;
return;
} //take care not to clobber an existing CDL
if (_cdl != null)
LoadFile(file.FullName); {
var result = MessageBox.Show(this, "OK to load new CDL?", "Query", MessageBoxButtons.YesNo);
if (result != DialogResult.Yes)
return;
}
LoadFile(file.FullName);
} }
void RunSave() void RunSave()
@ -319,120 +319,120 @@ namespace BizHawk.Client.EmuHawk
{ {
_cdl.Save(fs); _cdl.Save(fs);
} }
} }
private void SaveMenuItem_Click(object sender, EventArgs e) private void SaveMenuItem_Click(object sender, EventArgs e)
{ {
if (_cdl == null) if (_cdl == null)
{ {
MessageBox.Show(this, "Cannot save with no CDL loaded!", "Alert"); MessageBox.Show(this, "Cannot save with no CDL loaded!", "Alert");
return; return;
}
if (string.IsNullOrWhiteSpace(_currentFilename))
{
RunSaveAs();
return;
} }
RunSave(); if (string.IsNullOrWhiteSpace(_currentFilename))
} {
RunSaveAs();
return;
}
RunSave();
}
/// <summary> /// <summary>
/// returns false if the operation was canceled /// returns false if the operation was canceled
/// </summary> /// </summary>
bool RunSaveAs() bool RunSaveAs()
{ {
var file = SaveFileDialog( var file = SaveFileDialog(
_currentFilename, _currentFilename,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null),
"Code Data Logger Files", "Code Data Logger Files",
"cdl"); "cdl");
if (file == null) if (file == null)
return false; return false;
SetCurrentFilename(file.FullName); SetCurrentFilename(file.FullName);
RunSave(); RunSave();
return true; return true;
} }
private void SaveAsMenuItem_Click(object sender, EventArgs e) private void SaveAsMenuItem_Click(object sender, EventArgs e)
{ {
RunSaveAs(); RunSaveAs();
} }
private void AppendMenuItem_Click(object sender, EventArgs e) private void AppendMenuItem_Click(object sender, EventArgs e)
{ {
if (_cdl == null) if (_cdl == null)
{ {
MessageBox.Show(this, "Cannot append with no CDL loaded!", "Alert"); MessageBox.Show(this, "Cannot append with no CDL loaded!", "Alert");
} }
else else
{ {
var file = ToolFormBase.OpenFileDialog( var file = ToolFormBase.OpenFileDialog(
_currentFilename, _currentFilename,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null),
"Code Data Logger Files", "Code Data Logger Files",
"cdl"); "cdl");
if (file != null) if (file != null)
{ {
using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read)) using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{ {
var newCDL = new CodeDataLog(); var newCDL = new CodeDataLog();
newCDL.Load(fs); newCDL.Load(fs);
if (!_cdl.Check(newCDL)) if (!_cdl.Check(newCDL))
{ {
MessageBox.Show(this, "CDL file does not match emulator's current memory map!"); MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return; return;
} }
_cdl.LogicalOrFrom(newCDL); _cdl.LogicalOrFrom(newCDL);
UpdateDisplay(true); UpdateDisplay(true);
} }
} }
} }
} }
private void ClearMenuItem_Click(object sender, EventArgs e) private void ClearMenuItem_Click(object sender, EventArgs e)
{ {
if (_cdl == null) if (_cdl == null)
{ {
MessageBox.Show(this, "Cannot clear with no CDL loaded!", "Alert"); MessageBox.Show(this, "Cannot clear with no CDL loaded!", "Alert");
} }
else else
{ {
var result = MessageBox.Show(this, "OK to clear CDL?", "Query", MessageBoxButtons.YesNo); var result = MessageBox.Show(this, "OK to clear CDL?", "Query", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes) if (result == DialogResult.Yes)
{ {
_cdl.ClearData(); _cdl.ClearData();
UpdateDisplay(true); UpdateDisplay(true);
} }
} }
} }
private void DisassembleMenuItem_Click(object sender, EventArgs e) private void DisassembleMenuItem_Click(object sender, EventArgs e)
{ {
if (_cdl == null) if (_cdl == null)
{ {
MessageBox.Show(this, "Cannot disassemble with no CDL loaded!", "Alert"); MessageBox.Show(this, "Cannot disassemble with no CDL loaded!", "Alert");
return; return;
} }
var sfd = new SaveFileDialog(); var sfd = new SaveFileDialog();
var result = sfd.ShowDialog(this); var result = sfd.ShowDialog(this);
if (result == DialogResult.OK) if (result == DialogResult.OK)
{ {
using (var fs = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write)) using (var fs = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write))
{ {
CodeDataLogger.DisassembleCDL(fs, _cdl); CodeDataLogger.DisassembleCDL(fs, _cdl);
} }
} }
} }
private void ExitMenuItem_Click(object sender, EventArgs e) private void ExitMenuItem_Click(object sender, EventArgs e)
{ {
Close(); Close();
} }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
@ -447,69 +447,69 @@ namespace BizHawk.Client.EmuHawk
if (Global.Config.CDLAutoStart) if (Global.Config.CDLAutoStart)
NewFileLogic(); NewFileLogic();
base.OnShown(e); base.OnShown(e);
} }
protected override void OnClosed(EventArgs e) protected override void OnClosed(EventArgs e)
{ {
//deactivate logger //deactivate logger
if (CodeDataLogger != null) //just in case... if (CodeDataLogger != null) //just in case...
CodeDataLogger.SetCDL(null); CodeDataLogger.SetCDL(null);
} }
private void PCECDL_Load(object sender, EventArgs e) private void PCECDL_Load(object sender, EventArgs e)
{ {
} }
private void PCECDL_DragEnter(object sender, DragEventArgs e) private void PCECDL_DragEnter(object sender, DragEventArgs e)
{ {
e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None; e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None;
} }
private void PCECDL_DragDrop(object sender, DragEventArgs e) private void PCECDL_DragDrop(object sender, DragEventArgs e)
{ {
var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop); var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop);
if (Path.GetExtension(filePaths[0]) == ".cdl") if (Path.GetExtension(filePaths[0]) == ".cdl")
{ {
LoadFile(filePaths[0]); LoadFile(filePaths[0]);
} }
} }
private void tsbViewStyle_SelectedIndexChanged(object sender, EventArgs e) private void tsbViewStyle_SelectedIndexChanged(object sender, EventArgs e)
{ {
UpdateDisplay(true); UpdateDisplay(true);
} }
private void tsbLoggingActive_CheckedChanged(object sender, EventArgs e) private void tsbLoggingActive_CheckedChanged(object sender, EventArgs e)
{ {
if (tsbLoggingActive.Checked && _cdl == null) if (tsbLoggingActive.Checked && _cdl == null)
{ {
//implicitly create a new file //implicitly create a new file
NewFileLogic(); NewFileLogic();
} }
if (_cdl != null && tsbLoggingActive.Checked) if (_cdl != null && tsbLoggingActive.Checked)
CodeDataLogger.SetCDL(_cdl); CodeDataLogger.SetCDL(_cdl);
else else
CodeDataLogger.SetCDL(null); CodeDataLogger.SetCDL(null);
} }
private void lvCDL_QueryItemText(int item, int subItem, out string text) private void lvCDL_QueryItemText(int item, int subItem, out string text)
{ {
text = listContents[item][subItem]; text = listContents[item][subItem];
} }
private void tsbExportText_Click(object sender, EventArgs e) private void tsbExportText_Click(object sender, EventArgs e)
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
foreach(var line in listContents) foreach(var line in listContents)
{ {
foreach (var entry in line) foreach (var entry in line)
sw.Write("{0} |", entry); sw.Write("{0} |", entry);
sw.WriteLine(); sw.WriteLine();
} }
Clipboard.SetText(sw.ToString()); Clipboard.SetText(sw.ToString());
} }
private void miAutoSave_Click(object sender, EventArgs e) private void miAutoSave_Click(object sender, EventArgs e)
@ -522,6 +522,6 @@ namespace BizHawk.Client.EmuHawk
Global.Config.CDLAutoStart ^= true; Global.Config.CDLAutoStart ^= true;
} }
} }
} }

View File

@ -1,105 +1,105 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public partial class NewHexEditor : Form, IToolFormAutoConfig public partial class NewHexEditor : Form, IToolFormAutoConfig
{ {
#region Initialize and Dependencies #region Initialize and Dependencies
[RequiredService] [RequiredService]
private IMemoryDomains MemoryDomains { get; set; } private IMemoryDomains MemoryDomains { get; set; }
[RequiredService] [RequiredService]
private IEmulator Emulator { get; set; } private IEmulator Emulator { get; set; }
public NewHexEditor() public NewHexEditor()
{ {
InitializeComponent(); InitializeComponent();
Closing += (o, e) => SaveConfigSettings(); Closing += (o, e) => SaveConfigSettings();
HexViewControl.QueryIndexValue += HexView_QueryIndexValue; HexViewControl.QueryIndexValue += HexView_QueryIndexValue;
HexViewControl.QueryIndexForeColor += HexView_QueryIndexForeColor; HexViewControl.QueryIndexForeColor += HexView_QueryIndexForeColor;
HexViewControl.QueryIndexBgColor += HexView_QueryIndexForeColor; HexViewControl.QueryIndexBgColor += HexView_QueryIndexForeColor;
} }
private void NewHexEditor_Load(object sender, EventArgs e) private void NewHexEditor_Load(object sender, EventArgs e)
{ {
HexViewControl.ArrayLength = MemoryDomains.MainMemory.Size; HexViewControl.ArrayLength = MemoryDomains.MainMemory.Size;
} }
private void SaveConfigSettings() private void SaveConfigSettings()
{ {
} }
#endregion #endregion
#region IToolForm implementation #region IToolForm implementation
public void NewUpdate(ToolFormUpdateType type) { } public void NewUpdate(ToolFormUpdateType type) { }
public void UpdateValues() public void UpdateValues()
{ {
// TODO // TODO
} }
public void FastUpdate() public void FastUpdate()
{ {
// TODO // TODO
} }
public void Restart() public void Restart()
{ {
// TODO // TODO
} }
public bool AskSaveChanges() public bool AskSaveChanges()
{ {
return true; // TODO return true; // TODO
} }
public bool UpdateBefore { get { return false; } } public bool UpdateBefore { get { return false; } }
#endregion #endregion
#region HexView Callbacks #region HexView Callbacks
private void HexView_QueryIndexValue(int index, out long value) private void HexView_QueryIndexValue(int index, out long value)
{ {
value = MemoryDomains.MainMemory.PeekByte(index); value = MemoryDomains.MainMemory.PeekByte(index);
} }
private void HexView_QueryIndexBgColor(int index, ref Color color) private void HexView_QueryIndexBgColor(int index, ref Color color)
{ {
color = Color.White; color = Color.White;
} }
private void HexView_QueryIndexForeColor(int index, ref Color color) private void HexView_QueryIndexForeColor(int index, ref Color color)
{ {
color = Color.Black; color = Color.Black;
} }
#endregion #endregion
#region Menu Items #region Menu Items
private void FileSubMenu_DropDownOpened(object sender, EventArgs e) private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
{ {
} }
private void ExitMenuItem_Click(object sender, EventArgs e) private void ExitMenuItem_Click(object sender, EventArgs e)
{ {
Close(); Close();
} }
#endregion #endregion
} }
} }

View File

@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Emulation.Common.IEmulatorExtensions;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
{ {
/// <summary> /// <summary>
/// An implementation of ITraceable that is implementation using only methods /// An implementation of ITraceable that is implementation using only methods
@ -16,42 +16,42 @@ namespace BizHawk.Emulation.Common
/// <seealso cref="IDebuggable"/> /// <seealso cref="IDebuggable"/>
/// <seealso cref="IMemoryDomains"/> /// <seealso cref="IMemoryDomains"/>
/// <seealso cref="IDisassemblable"/> /// <seealso cref="IDisassemblable"/>
public abstract class CallbackBasedTraceBuffer : ITraceable public abstract class CallbackBasedTraceBuffer : ITraceable
{ {
public CallbackBasedTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler) public CallbackBasedTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler)
{ {
if (!debuggableCore.MemoryCallbacksAvailable()) if (!debuggableCore.MemoryCallbacksAvailable())
{ {
throw new InvalidOperationException("Memory callbacks are required"); throw new InvalidOperationException("Memory callbacks are required");
} }
try try
{ {
debuggableCore.GetCpuFlagsAndRegisters(); debuggableCore.GetCpuFlagsAndRegisters();
} }
catch (NotImplementedException) catch (NotImplementedException)
{ {
throw new InvalidOperationException("GetCpuFlagsAndRegisters is required"); throw new InvalidOperationException("GetCpuFlagsAndRegisters is required");
} }
Header = "Instructions"; Header = "Instructions";
DebuggableCore = debuggableCore; DebuggableCore = debuggableCore;
MemoryDomains = memoryDomains; MemoryDomains = memoryDomains;
Disassembler = disassembler; Disassembler = disassembler;
} }
protected readonly IMemoryDomains MemoryDomains; protected readonly IMemoryDomains MemoryDomains;
protected readonly IDisassemblable Disassembler; protected readonly IDisassemblable Disassembler;
protected readonly IDebuggable DebuggableCore; protected readonly IDebuggable DebuggableCore;
protected readonly List<TraceInfo> Buffer = new List<TraceInfo>(); protected readonly List<TraceInfo> Buffer = new List<TraceInfo>();
public abstract void TraceFromCallback(); public abstract void TraceFromCallback();
private ITraceSink _sink; private ITraceSink _sink;
public bool Enabled => Sink != null; public bool Enabled => Sink != null;
public void Put(TraceInfo info) public void Put(TraceInfo info)
{ {
Sink.Put(info); Sink.Put(info);
@ -73,26 +73,26 @@ namespace BizHawk.Emulation.Common
DebuggableCore.MemoryCallbacks.Add(new TracingMemoryCallback(TraceFromCallback)); DebuggableCore.MemoryCallbacks.Add(new TracingMemoryCallback(TraceFromCallback));
} }
} }
} }
public string Header { get; set; } public string Header { get; set; }
public class TracingMemoryCallback : IMemoryCallback public class TracingMemoryCallback : IMemoryCallback
{ {
public TracingMemoryCallback(Action callback) public TracingMemoryCallback(Action callback)
{ {
Callback = callback; Callback = callback;
} }
public MemoryCallbackType Type => MemoryCallbackType.Execute; public MemoryCallbackType Type => MemoryCallbackType.Execute;
public string Name => "Trace Logging"; public string Name => "Trace Logging";
public Action Callback { get; } public Action Callback { get; }
public uint? Address => null; public uint? Address => null;
public uint? AddressMask => null; public uint? AddressMask => null;
} }
} }
} }

View File

@ -1,120 +1,120 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using BizHawk.Emulation.Cores.Computers.Commodore64.Media; using BizHawk.Emulation.Cores.Computers.Commodore64.Media;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
{ {
public sealed partial class Drive1541 public sealed partial class Drive1541
{ {
[SaveState.DoNotSave] [SaveState.DoNotSave]
private const long LEHMER_RNG_PRIME = 48271; private const long LEHMER_RNG_PRIME = 48271;
[SaveState.SaveWithName("DiskDensityCounter")] [SaveState.SaveWithName("DiskDensityCounter")]
private int _diskDensityCounter; // density .. 16 private int _diskDensityCounter; // density .. 16
[SaveState.SaveWithName("DiskSupplementaryCounter")] [SaveState.SaveWithName("DiskSupplementaryCounter")]
private int _diskSupplementaryCounter; // 0 .. 16 private int _diskSupplementaryCounter; // 0 .. 16
[SaveState.SaveWithName("DiskFluxReversalDetected")] [SaveState.SaveWithName("DiskFluxReversalDetected")]
private bool _diskFluxReversalDetected; private bool _diskFluxReversalDetected;
[SaveState.SaveWithName("DiskBitsRemainingInDataEntry")] [SaveState.SaveWithName("DiskBitsRemainingInDataEntry")]
private int _diskBitsLeft; private int _diskBitsLeft;
[SaveState.SaveWithName("DiskDataEntryIndex")] [SaveState.SaveWithName("DiskDataEntryIndex")]
private int _diskByteOffset; private int _diskByteOffset;
[SaveState.SaveWithName("DiskDataEntry")] [SaveState.SaveWithName("DiskDataEntry")]
private int _diskBits; private int _diskBits;
[SaveState.SaveWithName("DiskCurrentCycle")] [SaveState.SaveWithName("DiskCurrentCycle")]
private int _diskCycle; private int _diskCycle;
[SaveState.SaveWithName("DiskDensityConfig")] [SaveState.SaveWithName("DiskDensityConfig")]
private int _diskDensity; private int _diskDensity;
[SaveState.SaveWithName("PreviousCA1")] [SaveState.SaveWithName("PreviousCA1")]
private bool _previousCa1; private bool _previousCa1;
[SaveState.SaveWithName("CountsBeforeRandomTransition")] [SaveState.SaveWithName("CountsBeforeRandomTransition")]
private int _countsBeforeRandomTransition; private int _countsBeforeRandomTransition;
[SaveState.SaveWithName("CurrentRNG")] [SaveState.SaveWithName("CurrentRNG")]
private int _rngCurrent; private int _rngCurrent;
[SaveState.SaveWithName("Clocks")] [SaveState.SaveWithName("Clocks")]
private int _clocks; private int _clocks;
[SaveState.SaveWithName("CpuClocks")] [SaveState.SaveWithName("CpuClocks")]
private int _cpuClocks; private int _cpuClocks;
// Lehmer RNG // Lehmer RNG
private void AdvanceRng() private void AdvanceRng()
{ {
if (_rngCurrent == 0) if (_rngCurrent == 0)
_rngCurrent = 1; _rngCurrent = 1;
_rngCurrent = (int)(_rngCurrent * LEHMER_RNG_PRIME % int.MaxValue); _rngCurrent = (int)(_rngCurrent * LEHMER_RNG_PRIME % int.MaxValue);
} }
private void ExecuteFlux() private void ExecuteFlux()
{ {
// This actually executes the main 16mhz clock // This actually executes the main 16mhz clock
while (_clocks > 0) while (_clocks > 0)
{ {
_clocks--; _clocks--;
// rotate disk // rotate disk
if (_motorEnabled) if (_motorEnabled)
{ {
if (_disk == null) if (_disk == null)
{
_diskBitsLeft = 1;
_diskBits = 0;
}
else
{
if (_diskBitsLeft <= 0)
{
_diskByteOffset++;
if (_diskByteOffset == Disk.FluxEntriesPerTrack)
{
_diskByteOffset = 0;
}
_diskBits = _trackImageData[_diskByteOffset];
_diskBitsLeft = Disk.FluxBitsPerEntry;
}
}
if ((_diskBits & 1) != 0)
{
_countsBeforeRandomTransition = 0;
_diskFluxReversalDetected = true;
}
_diskBits >>= 1;
_diskBitsLeft--;
}
// random flux transition readings for unformatted data
if (_countsBeforeRandomTransition > 0)
{
_countsBeforeRandomTransition--;
if (_countsBeforeRandomTransition == 0)
{
_diskFluxReversalDetected = true;
AdvanceRng();
// This constant is what VICE uses. TODO: Determine accuracy.
_countsBeforeRandomTransition = (_rngCurrent % 367) + 33;
}
}
// flux transition circuitry
if (_diskFluxReversalDetected)
{
_diskDensityCounter = _diskDensity;
_diskSupplementaryCounter = 0;
_diskFluxReversalDetected = false;
if (_countsBeforeRandomTransition == 0)
{ {
AdvanceRng(); _diskBitsLeft = 1;
// This constant is what VICE uses. TODO: Determine accuracy. _diskBits = 0;
_countsBeforeRandomTransition = (_rngCurrent & 0x1F) + 289; }
} else
} {
if (_diskBitsLeft <= 0)
// counter circuitry {
if (_diskDensityCounter >= 16) _diskByteOffset++;
{ if (_diskByteOffset == Disk.FluxEntriesPerTrack)
_diskDensityCounter = _diskDensity; {
_diskByteOffset = 0;
}
_diskBits = _trackImageData[_diskByteOffset];
_diskBitsLeft = Disk.FluxBitsPerEntry;
}
}
if ((_diskBits & 1) != 0)
{
_countsBeforeRandomTransition = 0;
_diskFluxReversalDetected = true;
}
_diskBits >>= 1;
_diskBitsLeft--;
}
// random flux transition readings for unformatted data
if (_countsBeforeRandomTransition > 0)
{
_countsBeforeRandomTransition--;
if (_countsBeforeRandomTransition == 0)
{
_diskFluxReversalDetected = true;
AdvanceRng();
// This constant is what VICE uses. TODO: Determine accuracy.
_countsBeforeRandomTransition = (_rngCurrent % 367) + 33;
}
}
// flux transition circuitry
if (_diskFluxReversalDetected)
{
_diskDensityCounter = _diskDensity;
_diskSupplementaryCounter = 0;
_diskFluxReversalDetected = false;
if (_countsBeforeRandomTransition == 0)
{
AdvanceRng();
// This constant is what VICE uses. TODO: Determine accuracy.
_countsBeforeRandomTransition = (_rngCurrent & 0x1F) + 289;
}
}
// counter circuitry
if (_diskDensityCounter >= 16)
{
_diskDensityCounter = _diskDensity;
_diskSupplementaryCounter++; _diskSupplementaryCounter++;
if ((_diskSupplementaryCounter & 0x3) == 0x2) if ((_diskSupplementaryCounter & 0x3) == 0x2)
{ {
_bitsRemainingInLatchedByte--; _bitsRemainingInLatchedByte--;
_byteReady = false; _byteReady = false;
@ -144,23 +144,23 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
_overflowFlagDelaySr |= _diskCycle > 6 ? 4 : 2; _overflowFlagDelaySr |= _diskCycle > 6 ? 4 : 2;
} }
} }
} }
if (_diskSupplementaryCounter >= 16) if (_diskSupplementaryCounter >= 16)
{ {
_diskSupplementaryCounter = 0; _diskSupplementaryCounter = 0;
} }
_cpuClocks--; _cpuClocks--;
if (_cpuClocks <= 0) if (_cpuClocks <= 0)
{ {
ExecuteSystem(); ExecuteSystem();
_cpuClocks = 16; _cpuClocks = 16;
} }
_diskDensityCounter++; _diskDensityCounter++;
_diskCycle = (_diskCycle + 1) & 0xF; _diskCycle = (_diskCycle + 1) & 0xF;
} }
} }
} }
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.User namespace BizHawk.Emulation.Cores.Computers.Commodore64.User
{ {
public sealed class UserPort public sealed class UserPort
{ {
@ -9,67 +9,67 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.User
public Func<bool> ReadCounter2; public Func<bool> ReadCounter2;
public Func<bool> ReadHandshake; public Func<bool> ReadHandshake;
public Func<bool> ReadSerial1; public Func<bool> ReadSerial1;
public Func<bool> ReadSerial2; public Func<bool> ReadSerial2;
private bool _connected;
private UserPortDevice _device;
public void Connect(UserPortDevice device)
{
_device = device;
_connected = _device != null;
if (_device != null)
{
_device.ReadCounter1 = () => ReadCounter1();
_device.ReadCounter2 = () => ReadCounter2();
_device.ReadHandshake = () => ReadHandshake();
_device.ReadSerial1 = () => ReadSerial1();
_device.ReadSerial2 = () => ReadSerial2();
}
}
public void Disconnect()
{
_connected = false;
_device = null;
}
public void HardReset() private bool _connected;
{ private UserPortDevice _device;
if (_connected)
{ public void Connect(UserPortDevice device)
_device.HardReset(); {
_device = device;
_connected = _device != null;
if (_device != null)
{
_device.ReadCounter1 = () => ReadCounter1();
_device.ReadCounter2 = () => ReadCounter2();
_device.ReadHandshake = () => ReadHandshake();
_device.ReadSerial1 = () => ReadSerial1();
_device.ReadSerial2 = () => ReadSerial2();
} }
} }
public bool ReadAtn() public void Disconnect()
{ {
return !_connected || _device.ReadAtn(); _connected = false;
_device = null;
}
public void HardReset()
{
if (_connected)
{
_device.HardReset();
}
}
public bool ReadAtn()
{
return !_connected || _device.ReadAtn();
} }
public int ReadData() public int ReadData()
{ {
return !_connected ? 0xFF : _device.ReadData(); return !_connected ? 0xFF : _device.ReadData();
} }
public bool ReadFlag2() public bool ReadFlag2()
{ {
return !_connected || _device.ReadFlag2(); return !_connected || _device.ReadFlag2();
} }
public bool ReadPa2() public bool ReadPa2()
{ {
return !_connected || _device.ReadPa2(); return !_connected || _device.ReadPa2();
} }
public bool ReadReset() public bool ReadReset()
{ {
return !_connected || _device.ReadReset(); return !_connected || _device.ReadReset();
} }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
SaveState.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -1,133 +1,133 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision namespace BizHawk.Emulation.Cores.Intellivision
{ {
public sealed partial class Intellivision public sealed partial class Intellivision
{ {
internal IMemoryDomains MemoryDomains; internal IMemoryDomains MemoryDomains;
private void SetupMemoryDomains() private void SetupMemoryDomains()
{ {
// TODO: is 8bit for byte arrays and 16bit for ushort correct here? // TODO: is 8bit for byte arrays and 16bit for ushort correct here?
// If ushort is correct, how about little endian? // If ushort is correct, how about little endian?
var domains = new List<MemoryDomain> var domains = new List<MemoryDomain>
{ {
new MemoryDomainDelegate( new MemoryDomainDelegate(
"Main RAM", "Main RAM",
ScratchpadRam.Length, ScratchpadRam.Length,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => ScratchpadRam[addr], addr => ScratchpadRam[addr],
(addr, value) => ScratchpadRam[addr] = value, (addr, value) => ScratchpadRam[addr] = value,
1), 1),
new MemoryDomainDelegate( new MemoryDomainDelegate(
"Graphics RAM", "Graphics RAM",
GraphicsRam.Length, GraphicsRam.Length,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => GraphicsRam[addr], addr => GraphicsRam[addr],
(addr, value) => GraphicsRam[addr] = value, (addr, value) => GraphicsRam[addr] = value,
1), 1),
new MemoryDomainDelegate( new MemoryDomainDelegate(
"Graphics ROM", "Graphics ROM",
GraphicsRom.Length, GraphicsRom.Length,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => GraphicsRom[addr], addr => GraphicsRom[addr],
(addr, value) => GraphicsRom[addr] = value, (addr, value) => GraphicsRom[addr] = value,
1), 1),
new MemoryDomainDelegate( new MemoryDomainDelegate(
"System Ram", "System Ram",
SystemRam.Length * 2, SystemRam.Length * 2,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => ReadByteFromShortArray(addr, SystemRam), addr => ReadByteFromShortArray(addr, SystemRam),
(addr, value) => WriteByteToShortArray(addr, value, SystemRam), (addr, value) => WriteByteToShortArray(addr, value, SystemRam),
1 1
), ),
new MemoryDomainDelegate( new MemoryDomainDelegate(
"Executive Rom", "Executive Rom",
ExecutiveRom.Length * 2, ExecutiveRom.Length * 2,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => ReadByteFromShortArray(addr, ExecutiveRom), addr => ReadByteFromShortArray(addr, ExecutiveRom),
(addr, value) => WriteByteToShortArray(addr, value, ExecutiveRom), (addr, value) => WriteByteToShortArray(addr, value, ExecutiveRom),
1 1
), ),
new MemoryDomainDelegate( new MemoryDomainDelegate(
"System Bus", "System Bus",
0X20000, 0X20000,
MemoryDomain.Endian.Little, MemoryDomain.Endian.Little,
addr => PeekSystemBus(addr), addr => PeekSystemBus(addr),
(addr, value) => PokeSystemBus(addr, value), (addr, value) => PokeSystemBus(addr, value),
1 1
) )
}; };
MemoryDomains = new MemoryDomainList(domains); MemoryDomains = new MemoryDomainList(domains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains); (ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
} }
private byte PeekSystemBus(long addr) private byte PeekSystemBus(long addr)
{ {
if (addr % 2 == 0) if (addr % 2 == 0)
{ {
long index = addr / 2; long index = addr / 2;
return (byte)(ReadMemory((ushort)index, true) >> 8); return (byte)(ReadMemory((ushort)index, true) >> 8);
}
else
{
long index = (addr - 1) / 2;
return (byte)(ReadMemory((ushort)index, true) & 0xFF);
} }
} else
{
long index = (addr - 1) / 2;
return (byte)(ReadMemory((ushort)index, true) & 0xFF);
}
}
private void PokeSystemBus(long addr, byte value) private void PokeSystemBus(long addr, byte value)
{ {
if (addr % 2 == 0) if (addr % 2 == 0)
{ {
long index = addr / 2; long index = addr / 2;
int temp = (ReadMemory((ushort)index, true) >> 8); int temp = (ReadMemory((ushort)index, true) >> 8);
WriteMemory((ushort)index, (ushort)(temp & (value << 8)), true); WriteMemory((ushort)index, (ushort)(temp & (value << 8)), true);
} }
else else
{ {
long index = (addr - 1) / 2; long index = (addr - 1) / 2;
int temp = ((ReadMemory((ushort)index, true) & 0xFF)<<8); int temp = ((ReadMemory((ushort)index, true) & 0xFF)<<8);
WriteMemory((ushort)index, (ushort)(temp & value), true); WriteMemory((ushort)index, (ushort)(temp & value), true);
} }
} }
// TODO: move these to a common library and maybe add an endian parameter // TODO: move these to a common library and maybe add an endian parameter
// Little endian // Little endian
private byte ReadByteFromShortArray(long addr, ushort[] array) private byte ReadByteFromShortArray(long addr, ushort[] array)
{ {
if (addr % 2 == 0) if (addr % 2 == 0)
{ {
long index = addr / 2; long index = addr / 2;
return (byte)(array[index] >> 8); return (byte)(array[index] >> 8);
} }
else else
{ {
long index = (addr - 1) / 2; long index = (addr - 1) / 2;
return (byte)(array[index] & 0xFF); return (byte)(array[index] & 0xFF);
} }
} }
private void WriteByteToShortArray(long addr, byte value, ushort[] array) private void WriteByteToShortArray(long addr, byte value, ushort[] array)
{ {
if (addr % 2 == 0) if (addr % 2 == 0)
{ {
long index = (addr - 1) / 2; long index = (addr - 1) / 2;
ushort val = (ushort)((value << 8) + (array[index] & 0xFF)); ushort val = (ushort)((value << 8) + (array[index] & 0xFF));
array[index] = val; array[index] = val;
} }
else else
{ {
long index = addr / 2; long index = addr / 2;
ushort val = (ushort)((((array[index] >> 8) & 0xFF) << 8) + value); ushort val = (ushort)((((array[index] >> 8) & 0xFF) << 8) + value);
array[index] = val; array[index] = val;
} }
} }
} }
} }

View File

@ -1,60 +1,60 @@
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
// Adapted from Nestopia src // Adapted from Nestopia src
public sealed class Mapper121 : MMC3Board_Base public sealed class Mapper121 : MMC3Board_Base
{ {
private ByteBuffer exRegs = new ByteBuffer(3); private ByteBuffer exRegs = new ByteBuffer(3);
private readonly byte[] lut = { 0x00, 0x83, 0x42, 0x00 }; private readonly byte[] lut = { 0x00, 0x83, 0x42, 0x00 };
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER121": case "MAPPER121":
break; break;
default: default:
return false; return false;
} }
BaseSetup(); BaseSetup();
return true; return true;
} }
public override void Dispose() public override void Dispose()
{ {
exRegs.Dispose(); exRegs.Dispose();
base.Dispose(); base.Dispose();
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("exRegs", ref exRegs);
}
public override byte ReadEXP(int addr)
{
if (addr >= 0x1000)
{
return exRegs[2];
}
else
{
return base.ReadEXP(addr);
}
} }
public override void WriteEXP(int addr, byte value) public override void SyncState(Serializer ser)
{ {
base.SyncState(ser);
ser.Sync("exRegs", ref exRegs);
}
public override byte ReadEXP(int addr)
{
if (addr >= 0x1000)
{
return exRegs[2];
}
else
{
return base.ReadEXP(addr);
}
}
public override void WriteEXP(int addr, byte value)
{
if (addr >= 0x1000) // 0x5000-0x5FFF if (addr >= 0x1000) // 0x5000-0x5FFF
{ {
exRegs[2] = lut[value & 0x3]; exRegs[2] = lut[value & 0x3];
} }
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)
{ {
int bank_8k = addr >> 13; int bank_8k = addr >> 13;
@ -73,38 +73,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
bank_8k &= prg_mask; bank_8k &= prg_mask;
addr = (bank_8k << 13) | (addr & 0x1FFF); addr = (bank_8k << 13) | (addr & 0x1FFF);
return ROM[addr]; return ROM[addr];
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)
{ {
if (addr < 0x2000) if (addr < 0x2000)
{ {
if ((addr & 3) == 3) if ((addr & 3) == 3)
{ {
switch (value) switch (value)
{ {
case 0x28: exRegs[0] = 0x0C; break; case 0x28: exRegs[0] = 0x0C; break;
case 0x26: exRegs[1] = 0x08; break; case 0x26: exRegs[1] = 0x08; break;
case 0xAB: exRegs[1] = 0x07; break; case 0xAB: exRegs[1] = 0x07; break;
case 0xEC: exRegs[1] = 0x0D; break; case 0xEC: exRegs[1] = 0x0D; break;
case 0xEF: exRegs[1] = 0x0D; break; case 0xEF: exRegs[1] = 0x0D; break;
case 0xFF: exRegs[1] = 0x09; break; case 0xFF: exRegs[1] = 0x09; break;
case 0x20: exRegs[1] = 0x13; break; case 0x20: exRegs[1] = 0x13; break;
case 0x29: exRegs[1] = 0x1B; break; case 0x29: exRegs[1] = 0x1B; break;
default: exRegs[0] = 0x0; exRegs[1] = 0x0; break; default: exRegs[0] = 0x0; exRegs[1] = 0x0; break;
} }
} }
else if ((addr & 1)>0) else if ((addr & 1)>0)
base.WritePRG(addr, value); base.WritePRG(addr, value);
else //if (addr==0) else //if (addr==0)
base.WritePRG(0, value); base.WritePRG(0, value);
} }
else else
{ {
base.WritePRG(addr, value); base.WritePRG(addr, value);
} }
} }
} }
} }

View File

@ -1,6 +1,6 @@
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public sealed class Mapper219 : MMC3Board_Base public sealed class Mapper219 : MMC3Board_Base
{ {
public byte[] exregs = new byte[3]; public byte[] exregs = new byte[3];
public byte[] prgregs = new byte[4]; public byte[] prgregs = new byte[4];
@ -8,22 +8,22 @@
public byte bits_rev, reg_value; public byte bits_rev, reg_value;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER219": case "MAPPER219":
break; break;
default: default:
return false; return false;
} }
BaseSetup(); BaseSetup();
prgregs[1] = 1; prgregs[1] = 1;
prgregs[2] = 2; prgregs[2] = 2;
prgregs[3] = 3; prgregs[3] = 3;
byte r0_0 = (byte)(0 & ~1); byte r0_0 = (byte)(0 & ~1);
byte r0_1 = (byte)(0 | 1); byte r0_1 = (byte)(0 | 1);
byte r1_0 = (byte)(2 & ~1); byte r1_0 = (byte)(2 & ~1);
@ -46,11 +46,11 @@
chr_regs_1k[4] = regs[2]; chr_regs_1k[4] = regs[2];
chr_regs_1k[5] = regs[3]; chr_regs_1k[5] = regs[3];
chr_regs_1k[6] = regs[4]; chr_regs_1k[6] = regs[4];
chr_regs_1k[7] = regs[5];*/ chr_regs_1k[7] = regs[5];*/
return true; return true;
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)
{ {
if (addr<0x2000) if (addr<0x2000)
@ -103,8 +103,8 @@
} }
else else
base.WritePRG(addr, value); base.WritePRG(addr, value);
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)
{ {
int bank_prg = addr >> 13; int bank_prg = addr >> 13;
@ -122,8 +122,8 @@
} }
else else
return base.ReadPPU(addr); return base.ReadPPU(addr);
} }
public override void WritePPU(int addr, byte value) public override void WritePPU(int addr, byte value)
{ {
if (addr < 0x2000) if (addr < 0x2000)
@ -134,6 +134,6 @@
} }
else else
base.WritePPU(addr, value); base.WritePPU(addr, value);
} }
} }
} }

View File

@ -1,27 +1,27 @@
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
// TODO // TODO
public sealed class Mapper223 : MMC3Board_Base public sealed class Mapper223 : MMC3Board_Base
{ {
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER223": case "MAPPER223":
break; break;
default: default:
return false; return false;
} }
BaseSetup(); BaseSetup();
mmc3.wram_enable = true; mmc3.wram_enable = true;
mmc3.wram_write_protect = true; mmc3.wram_write_protect = true;
return true; return true;
} }
public override void WriteEXP(int addr, byte value) public override void WriteEXP(int addr, byte value)
{ {
if (addr>0x1000) if (addr>0x1000)
@ -30,8 +30,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
} }
else else
base.WriteEXP(addr, value); base.WriteEXP(addr, value);
} }
public override byte ReadEXP(int addr) public override byte ReadEXP(int addr)
{ {
if (addr > 0x1000) if (addr > 0x1000)
@ -40,6 +40,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
} }
else else
return base.ReadEXP(addr); return base.ReadEXP(addr);
} }
} }
} }

View File

@ -1,72 +1,72 @@
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public sealed class Mapper125 : NES.NESBoardBase public sealed class Mapper125 : NES.NESBoardBase
{ {
private byte reg; private byte reg;
private int prg_bank_mask_8k; private int prg_bank_mask_8k;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER125": case "MAPPER125":
case "UNIF_UNL-LH32": case "UNIF_UNL-LH32":
break; break;
default: default:
return false; return false;
} }
SetMirrorType(Cart.pad_h, Cart.pad_v); SetMirrorType(Cart.pad_h, Cart.pad_v);
prg_bank_mask_8k = Cart.prg_size / 8 - 1; prg_bank_mask_8k = Cart.prg_size / 8 - 1;
return true; return true;
} }
public override void SyncState(Serializer ser) public override void SyncState(Serializer ser)
{ {
ser.Sync("reg", ref reg); ser.Sync("reg", ref reg);
base.SyncState(ser); base.SyncState(ser);
} }
public override void WriteWRAM(int addr, byte value) public override void WriteWRAM(int addr, byte value)
{ {
if (addr == 0) if (addr == 0)
{ {
reg = value; reg = value;
} }
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)
{ {
if ((addr >= 0x4000) && (addr < 0x6000)) if ((addr >= 0x4000) && (addr < 0x6000))
WRAM[addr - 0x4000] = value; WRAM[addr - 0x4000] = value;
else else
base.WritePRG(addr, value); base.WritePRG(addr, value);
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)
{ {
int bank = 0; int bank = 0;
if (addr < 0x2000) { bank = prg_bank_mask_8k - 3; } if (addr < 0x2000) { bank = prg_bank_mask_8k - 3; }
else if (addr < 0x4000) { bank = prg_bank_mask_8k - 2; } else if (addr < 0x4000) { bank = prg_bank_mask_8k - 2; }
// for some reason WRAM is mapped to here. // for some reason WRAM is mapped to here.
else if (addr < 0x6000) else if (addr < 0x6000)
{ {
return WRAM[addr - 0x4000]; return WRAM[addr - 0x4000];
} }
else { bank = prg_bank_mask_8k; } else { bank = prg_bank_mask_8k; }
bank &= prg_bank_mask_8k; bank &= prg_bank_mask_8k;
return ROM[(bank << 13) + (addr & 0x1FFF)]; return ROM[(bank << 13) + (addr & 0x1FFF)];
} }
public override byte ReadWRAM(int addr) public override byte ReadWRAM(int addr)
{ {
return ROM[((reg & prg_bank_mask_8k) << 13) + addr]; return ROM[((reg & prg_bank_mask_8k) << 13) + addr];
} }
} }
} }

View File

@ -1,128 +1,128 @@
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public sealed class Mapper142 : NES.NESBoardBase public sealed class Mapper142 : NES.NESBoardBase
{ {
private ByteBuffer reg = new ByteBuffer(8); private ByteBuffer reg = new ByteBuffer(8);
private byte cmd; private byte cmd;
private int lastBank; private int lastBank;
private bool isirqused = false; private bool isirqused = false;
private byte IRQa = 0; private byte IRQa = 0;
private int IRQCount = 0; private int IRQCount = 0;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER142": case "MAPPER142":
case "UNIF_UNL-KS7032": case "UNIF_UNL-KS7032":
break; break;
default: default:
return false; return false;
} }
SetMirrorType(EMirrorType.Horizontal); SetMirrorType(EMirrorType.Horizontal);
lastBank = Cart.prg_size / 8 - 1; lastBank = Cart.prg_size / 8 - 1;
return true; return true;
} }
public override void Dispose() public override void Dispose()
{ {
reg.Dispose(); reg.Dispose();
base.Dispose(); base.Dispose();
} }
public override byte ReadWRAM(int addr) public override byte ReadWRAM(int addr)
{ {
return ROM[(reg[4] << 13) + (addr & 0x1FFF)]; return ROM[(reg[4] << 13) + (addr & 0x1FFF)];
} }
public override byte ReadPRG(int addr) public override byte ReadPRG(int addr)
{ {
if (addr < 0x2000) { return ROM[(reg[1] << 13) + (addr & 0x1FFF)]; } if (addr < 0x2000) { return ROM[(reg[1] << 13) + (addr & 0x1FFF)]; }
if (addr < 0x4000) { return ROM[(reg[2] << 13) + (addr & 0x1FFF)]; } if (addr < 0x4000) { return ROM[(reg[2] << 13) + (addr & 0x1FFF)]; }
if (addr < 0x6000) { return ROM[(reg[3] << 13) + (addr & 0x1FFF)]; } if (addr < 0x6000) { return ROM[(reg[3] << 13) + (addr & 0x1FFF)]; }
return ROM[(lastBank << 13) + (addr & 0x1FFF)]; return ROM[(lastBank << 13) + (addr & 0x1FFF)];
} }
public override void WriteEXP(int addr, byte value) public override void WriteEXP(int addr, byte value)
{ {
Write(addr + 0x4000, value); Write(addr + 0x4000, value);
} }
public override void WriteWRAM(int addr, byte value) public override void WriteWRAM(int addr, byte value)
{ {
Write(addr + 0x6000, value); Write(addr + 0x6000, value);
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)
{ {
Write(addr + 0x8000, value); Write(addr + 0x8000, value);
} }
private void IRQHook(int a) private void IRQHook(int a)
{ {
if (IRQa > 0) if (IRQa > 0)
{ {
IRQCount += a; IRQCount += a;
if (IRQCount >= 0xFFFF) if (IRQCount >= 0xFFFF)
{ {
IRQa = 0; IRQa = 0;
IRQCount = 0; IRQCount = 0;
IRQSignal = true; IRQSignal = true;
} }
} }
} }
public override void ClockPPU() public override void ClockPPU()
{ {
IRQHook(1); IRQHook(1);
} }
private void Write(int addr, byte value) private void Write(int addr, byte value)
{ {
switch (addr & 0xF000) switch (addr & 0xF000)
{ {
case 0x8000: case 0x8000:
IRQSignal = false; IRQSignal = false;
IRQCount = (IRQCount & 0x000F) | (value & 0x0F); IRQCount = (IRQCount & 0x000F) | (value & 0x0F);
isirqused = true; isirqused = true;
break; break;
case 0x9000: case 0x9000:
IRQSignal = false; IRQSignal = false;
IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4); IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4);
isirqused = true; isirqused = true;
break; break;
case 0xA000: case 0xA000:
IRQSignal = false; IRQSignal = false;
IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8); IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8);
isirqused = true; isirqused = true;
break; break;
case 0xB000: case 0xB000:
IRQSignal = false; IRQSignal = false;
IRQCount = (IRQCount & 0xF000) | (value << 12); IRQCount = (IRQCount & 0xF000) | (value << 12);
isirqused = true; isirqused = true;
break; break;
case 0xC000: case 0xC000:
if (isirqused) if (isirqused)
{ {
IRQSignal = false; IRQSignal = false;
IRQa = 1; IRQa = 1;
} }
break; break;
case 0xE000: case 0xE000:
cmd = (byte)(value & 7); cmd = (byte)(value & 7);
break; break;
case 0xF000: case 0xF000:
reg[cmd] = value; reg[cmd] = value;
break; break;
} }
} }
} }
} }

View File

@ -29,12 +29,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
static readonly float[] hi_levels = { 0.40f, 0.68f, 1.00f, 1.00f }; static readonly float[] hi_levels = { 0.40f, 0.68f, 1.00f, 1.00f };
static readonly byte[] tints = { 0, 6, 10, 8, 2, 4, 0, 0 }; static readonly byte[] tints = { 0, 6, 10, 8, 2, 4, 0, 0 };
static readonly float[] phases = static readonly float[] phases =
{ {
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f, -1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
1.0f, 0.866025f, 0.5f, 0.0f, -0.5f, -0.866025f, 1.0f, 0.866025f, 0.5f, 0.0f, -0.5f, -0.866025f,
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f, -1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
1.0f 1.0f
}; };
public static void Emphasis(byte[] inp, byte[] outp, int entrynum) public static void Emphasis(byte[] inp, byte[] outp, int entrynum)

View File

@ -1,278 +1,278 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization; using System.Globalization;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{ {
public partial class GPGX : ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings> public partial class GPGX : ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings>
{ {
public GPGXSettings GetSettings() public GPGXSettings GetSettings()
{ {
return _settings.Clone(); return _settings.Clone();
} }
public GPGXSyncSettings GetSyncSettings() public GPGXSyncSettings GetSyncSettings()
{ {
return _syncSettings.Clone(); return _syncSettings.Clone();
} }
public bool PutSettings(GPGXSettings o) public bool PutSettings(GPGXSettings o)
{ {
bool ret = GPGXSettings.NeedsReboot(_settings, o); bool ret = GPGXSettings.NeedsReboot(_settings, o);
_settings = o; _settings = o;
LibGPGX.gpgx_set_draw_mask(_settings.GetDrawMask()); LibGPGX.gpgx_set_draw_mask(_settings.GetDrawMask());
return ret; return ret;
} }
public bool PutSyncSettings(GPGXSyncSettings o) public bool PutSyncSettings(GPGXSyncSettings o)
{ {
bool ret = GPGXSyncSettings.NeedsReboot(_syncSettings, o); bool ret = GPGXSyncSettings.NeedsReboot(_syncSettings, o);
_syncSettings = o; _syncSettings = o;
return ret; return ret;
} }
private class UintToHexConverter : TypeConverter private class UintToHexConverter : TypeConverter
{ {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{ {
if (sourceType == typeof(string)) if (sourceType == typeof(string))
{ {
return true; return true;
} }
else else
{ {
return base.CanConvertFrom(context, sourceType); return base.CanConvertFrom(context, sourceType);
} }
} }
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{ {
if (destinationType == typeof(string)) if (destinationType == typeof(string))
{ {
return true; return true;
} }
else else
{ {
return base.CanConvertTo(context, destinationType); return base.CanConvertTo(context, destinationType);
} }
} }
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{ {
if (destinationType == typeof(string) && value.GetType() == typeof(uint)) if (destinationType == typeof(string) && value.GetType() == typeof(uint))
{ {
return string.Format("0x{0:x8}", value); return string.Format("0x{0:x8}", value);
} }
else else
{ {
return base.ConvertTo(context, culture, value, destinationType); return base.ConvertTo(context, culture, value, destinationType);
} }
} }
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{ {
if (value.GetType() == typeof(string)) if (value.GetType() == typeof(string))
{ {
string input = (string)value; string input = (string)value;
if (input.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) if (input.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{ {
input = input.Substring(2); input = input.Substring(2);
} }
return uint.Parse(input, NumberStyles.HexNumber, culture); return uint.Parse(input, NumberStyles.HexNumber, culture);
} }
else else
{ {
return base.ConvertFrom(context, culture, value); return base.ConvertFrom(context, culture, value);
} }
} }
} }
private GPGXSyncSettings _syncSettings; private GPGXSyncSettings _syncSettings;
private GPGXSettings _settings; private GPGXSettings _settings;
public class GPGXSettings public class GPGXSettings
{ {
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _DrawBGA; private bool _DrawBGA;
[DisplayName("Background Layer A")] [DisplayName("Background Layer A")]
[Description("True to draw BG layer A")] [Description("True to draw BG layer A")]
[DefaultValue(true)] [DefaultValue(true)]
public bool DrawBGA { get { return _DrawBGA; } set { _DrawBGA = value; } } public bool DrawBGA { get { return _DrawBGA; } set { _DrawBGA = value; } }
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _DrawBGB; private bool _DrawBGB;
[DisplayName("Background Layer B")] [DisplayName("Background Layer B")]
[Description("True to draw BG layer B")] [Description("True to draw BG layer B")]
[DefaultValue(true)] [DefaultValue(true)]
public bool DrawBGB { get { return _DrawBGB; } set { _DrawBGB = value; } } public bool DrawBGB { get { return _DrawBGB; } set { _DrawBGB = value; } }
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _DrawBGW; private bool _DrawBGW;
[DisplayName("Background Layer W")] [DisplayName("Background Layer W")]
[Description("True to draw BG layer W")] [Description("True to draw BG layer W")]
[DefaultValue(true)] [DefaultValue(true)]
public bool DrawBGW { get { return _DrawBGW; } set { _DrawBGW = value; } } public bool DrawBGW { get { return _DrawBGW; } set { _DrawBGW = value; } }
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _DrawObj; private bool _DrawObj;
[DisplayName("Sprite Layer")] [DisplayName("Sprite Layer")]
[Description("True to draw sprite layer")] [Description("True to draw sprite layer")]
[DefaultValue(true)] [DefaultValue(true)]
public bool DrawObj { get { return _DrawObj; } set { _DrawObj = value; } } public bool DrawObj { get { return _DrawObj; } set { _DrawObj = value; } }
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _PadScreen320; private bool _PadScreen320;
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _AlwaysDoubleSize; private bool _AlwaysDoubleSize;
[DisplayName("Pad screen to 320")] [DisplayName("Pad screen to 320")]
[Description("Set to True to pad the screen out to be 320 when in 256 wide video modes")] [Description("Set to True to pad the screen out to be 320 when in 256 wide video modes")]
[DefaultValue(false)] [DefaultValue(false)]
public bool PadScreen320 { get { return _PadScreen320; } set { _PadScreen320 = value; } } public bool PadScreen320 { get { return _PadScreen320; } set { _PadScreen320 = value; } }
[DisplayName("Always double-size")] [DisplayName("Always double-size")]
[Description("Set to True to convert the video to high-resolution mode even when it's low resolution so that the window doesn't change size between game modes")] [Description("Set to True to convert the video to high-resolution mode even when it's low resolution so that the window doesn't change size between game modes")]
[DefaultValue(false)] [DefaultValue(false)]
public bool AlwaysDoubleSize { get { return _AlwaysDoubleSize; } set { _AlwaysDoubleSize = value; } } public bool AlwaysDoubleSize { get { return _AlwaysDoubleSize; } set { _AlwaysDoubleSize = value; } }
[DisplayName("Audio Filter")] [DisplayName("Audio Filter")]
[DefaultValue(LibGPGX.InitSettings.FilterType.LowPass)] [DefaultValue(LibGPGX.InitSettings.FilterType.LowPass)]
public LibGPGX.InitSettings.FilterType Filter { get; set; } public LibGPGX.InitSettings.FilterType Filter { get; set; }
[DisplayName("Low Pass Range")] [DisplayName("Low Pass Range")]
[Description("Only active when filter type is lowpass")] [Description("Only active when filter type is lowpass")]
[DefaultValue((ushort)39321)] [DefaultValue((ushort)39321)]
public ushort LowPassRange { get; set; } public ushort LowPassRange { get; set; }
[DisplayName("Three band low cutoff")] [DisplayName("Three band low cutoff")]
[Description("Only active when filter type is three band")] [Description("Only active when filter type is three band")]
[DefaultValue((short)880)] [DefaultValue((short)880)]
public short LowFreq { get; set; } public short LowFreq { get; set; }
[DisplayName("Three band high cutoff")] [DisplayName("Three band high cutoff")]
[Description("Only active when filter type is three band")] [Description("Only active when filter type is three band")]
[DefaultValue((short)5000)] [DefaultValue((short)5000)]
public short HighFreq { get; set; } public short HighFreq { get; set; }
[DisplayName("Three band low gain")] [DisplayName("Three band low gain")]
[Description("Only active when filter type is three band")] [Description("Only active when filter type is three band")]
[DefaultValue((short)1)] [DefaultValue((short)1)]
public short LowGain { get; set; } public short LowGain { get; set; }
[DisplayName("Three band mid gain")] [DisplayName("Three band mid gain")]
[Description("Only active when filter type is three band")] [Description("Only active when filter type is three band")]
[DefaultValue((short)1)] [DefaultValue((short)1)]
public short MidGain { get; set; } public short MidGain { get; set; }
[DisplayName("Three band high gain")] [DisplayName("Three band high gain")]
[Description("Only active when filter type is three band")] [Description("Only active when filter type is three band")]
[DefaultValue((short)1)] [DefaultValue((short)1)]
public short HighGain { get; set; } public short HighGain { get; set; }
[DeepEqualsIgnore] [DeepEqualsIgnore]
[JsonIgnore] [JsonIgnore]
private bool _Backdrop; private bool _Backdrop;
[DisplayName("Use custom backdrop color")] [DisplayName("Use custom backdrop color")]
[Description("Filler when layers are off")] [Description("Filler when layers are off")]
[DefaultValue((bool)false)] [DefaultValue((bool)false)]
public bool Backdrop { get { return _Backdrop; } set { _Backdrop = value; } } public bool Backdrop { get { return _Backdrop; } set { _Backdrop = value; } }
[DisplayName("Custom backdrop color")] [DisplayName("Custom backdrop color")]
[Description("Magic pink by default. Requires core reboot")] [Description("Magic pink by default. Requires core reboot")]
[TypeConverter(typeof(UintToHexConverter))] [TypeConverter(typeof(UintToHexConverter))]
[DefaultValue((uint)0xffff00ff)] [DefaultValue((uint)0xffff00ff)]
public uint BackdropColor { get; set; } public uint BackdropColor { get; set; }
public GPGXSettings() public GPGXSettings()
{ {
SettingsUtil.SetDefaultValues(this); SettingsUtil.SetDefaultValues(this);
} }
public GPGXSettings Clone() public GPGXSettings Clone()
{ {
return (GPGXSettings)MemberwiseClone(); return (GPGXSettings)MemberwiseClone();
} }
public LibGPGX.DrawMask GetDrawMask() public LibGPGX.DrawMask GetDrawMask()
{ {
LibGPGX.DrawMask ret = 0; LibGPGX.DrawMask ret = 0;
if (DrawBGA) ret |= LibGPGX.DrawMask.BGA; if (DrawBGA) ret |= LibGPGX.DrawMask.BGA;
if (DrawBGB) ret |= LibGPGX.DrawMask.BGB; if (DrawBGB) ret |= LibGPGX.DrawMask.BGB;
if (DrawBGW) ret |= LibGPGX.DrawMask.BGW; if (DrawBGW) ret |= LibGPGX.DrawMask.BGW;
if (DrawObj) ret |= LibGPGX.DrawMask.Obj; if (DrawObj) ret |= LibGPGX.DrawMask.Obj;
if (Backdrop) ret |= LibGPGX.DrawMask.Backdrop; if (Backdrop) ret |= LibGPGX.DrawMask.Backdrop;
return ret; return ret;
} }
public static bool NeedsReboot(GPGXSettings x, GPGXSettings y) public static bool NeedsReboot(GPGXSettings x, GPGXSettings y)
{ {
return !DeepEquality.DeepEquals(x, y); return !DeepEquality.DeepEquals(x, y);
} }
public LibGPGX.InitSettings GetNativeSettings() public LibGPGX.InitSettings GetNativeSettings()
{ {
return new LibGPGX.InitSettings return new LibGPGX.InitSettings
{ {
Filter = Filter, Filter = Filter,
LowPassRange = LowPassRange, LowPassRange = LowPassRange,
LowFreq = LowFreq, LowFreq = LowFreq,
HighFreq = HighFreq, HighFreq = HighFreq,
LowGain = LowGain, LowGain = LowGain,
MidGain = MidGain, MidGain = MidGain,
HighGain = HighGain, HighGain = HighGain,
BackdropColor = BackdropColor BackdropColor = BackdropColor
}; };
} }
} }
public class GPGXSyncSettings public class GPGXSyncSettings
{ {
[DisplayName("Use Six Button Controllers")] [DisplayName("Use Six Button Controllers")]
[Description("Controls the type of any attached normal controllers; six button controllers are used if true, otherwise three button controllers. Some games don't work correctly with six button controllers. Not relevant if other controller types are connected.")] [Description("Controls the type of any attached normal controllers; six button controllers are used if true, otherwise three button controllers. Some games don't work correctly with six button controllers. Not relevant if other controller types are connected.")]
[DefaultValue(true)] [DefaultValue(true)]
public bool UseSixButton { get; set; } public bool UseSixButton { get; set; }
[DisplayName("Control Type")] [DisplayName("Control Type")]
[Description("Sets the type of controls that are plugged into the console. Some games will automatically load with a different control type.")] [Description("Sets the type of controls that are plugged into the console. Some games will automatically load with a different control type.")]
[DefaultValue(ControlType.Normal)] [DefaultValue(ControlType.Normal)]
public ControlType ControlType { get; set; } public ControlType ControlType { get; set; }
[DisplayName("Autodetect Region")] [DisplayName("Autodetect Region")]
[Description("Sets the region of the emulated console. Many games can run on multiple regions and will behave differently on different ones. Some games may require a particular region.")] [Description("Sets the region of the emulated console. Many games can run on multiple regions and will behave differently on different ones. Some games may require a particular region.")]
[DefaultValue(LibGPGX.Region.Autodetect)] [DefaultValue(LibGPGX.Region.Autodetect)]
public LibGPGX.Region Region { get; set; } public LibGPGX.Region Region { get; set; }
public GPGXSyncSettings() public GPGXSyncSettings()
{ {
SettingsUtil.SetDefaultValues(this); SettingsUtil.SetDefaultValues(this);
} }
public GPGXSyncSettings Clone() public GPGXSyncSettings Clone()
{ {
return (GPGXSyncSettings)MemberwiseClone(); return (GPGXSyncSettings)MemberwiseClone();
} }
public static bool NeedsReboot(GPGXSyncSettings x, GPGXSyncSettings y) public static bool NeedsReboot(GPGXSyncSettings x, GPGXSyncSettings y)
{ {
return !DeepEquality.DeepEquals(x, y); return !DeepEquality.DeepEquals(x, y);
} }
} }
} }
} }

View File

@ -1,54 +1,54 @@
using System; using System;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{ {
public partial class GPGX : IVideoProvider public partial class GPGX : IVideoProvider
{ {
public int[] GetVideoBuffer() { return vidbuff; } public int[] GetVideoBuffer() { return vidbuff; }
public int VirtualWidth { get { return 320; } } public int VirtualWidth { get { return 320; } }
public int VirtualHeight { get { return 224; } } public int VirtualHeight { get { return 224; } }
public int BufferWidth { get { return vwidth; } } public int BufferWidth { get { return vwidth; } }
public int BufferHeight { get { return vheight; } } public int BufferHeight { get { return vheight; } }
public int BackgroundColor { get { return unchecked((int)0xff000000); } } public int BackgroundColor { get { return unchecked((int)0xff000000); } }
private int[] vidbuff = new int[0]; private int[] vidbuff = new int[0];
private int vwidth; private int vwidth;
private int vheight; private int vheight;
private void UpdateVideoInitial() private void UpdateVideoInitial()
{ {
// hack: you should call update_video() here, but that gives you 256x192 on frame 0 // hack: you should call update_video() here, but that gives you 256x192 on frame 0
// and we know that we only use GPGX to emulate genesis games that will always be 320x224 immediately afterwards // and we know that we only use GPGX to emulate genesis games that will always be 320x224 immediately afterwards
// so instead, just assume a 320x224 size now; if that happens to be wrong, it'll be fixed soon enough. // so instead, just assume a 320x224 size now; if that happens to be wrong, it'll be fixed soon enough.
vwidth = 320; vwidth = 320;
vheight = 224; vheight = 224;
vidbuff = new int[vwidth * vheight]; vidbuff = new int[vwidth * vheight];
for (int i = 0; i < vidbuff.Length; i++) for (int i = 0; i < vidbuff.Length; i++)
vidbuff[i] = unchecked((int)0xff000000); vidbuff[i] = unchecked((int)0xff000000);
} }
private unsafe void UpdateVideo() private unsafe void UpdateVideo()
{ {
int gppitch, gpwidth, gpheight; int gppitch, gpwidth, gpheight;
IntPtr src = IntPtr.Zero; IntPtr src = IntPtr.Zero;
LibGPGX.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src); LibGPGX.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src);
//in case we're receiving high vertical resolution video, we shall double the horizontal resolution to keep the same proportions //in case we're receiving high vertical resolution video, we shall double the horizontal resolution to keep the same proportions
//(concept pioneered for snes) //(concept pioneered for snes)
bool dotDouble = (gpheight == 448); //todo: pal? bool dotDouble = (gpheight == 448); //todo: pal?
bool lineDouble = false; bool lineDouble = false;
vwidth = gpwidth; vwidth = gpwidth;
vheight = gpheight; vheight = gpheight;
if (_settings.AlwaysDoubleSize) if (_settings.AlwaysDoubleSize)
@ -61,15 +61,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
} }
} }
if (_settings.PadScreen320 && vwidth == 256) if (_settings.PadScreen320 && vwidth == 256)
vwidth = 320; vwidth = 320;
int xpad = (vwidth - gpwidth) / 2; int xpad = (vwidth - gpwidth) / 2;
int xpad2 = vwidth - gpwidth - xpad; int xpad2 = vwidth - gpwidth - xpad;
if (dotDouble) vwidth *= 2; if (dotDouble) vwidth *= 2;
if (vidbuff.Length < vwidth * vheight) if (vidbuff.Length < vwidth * vheight)
vidbuff = new int[vwidth * vheight]; vidbuff = new int[vwidth * vheight];
int xskip = 1; int xskip = 1;
@ -112,8 +112,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
psrc += rinc; psrc += rinc;
} }
} }
} }
} }
} }
} }

View File

@ -1,48 +1,48 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Sony.PSX namespace BizHawk.Emulation.Cores.Sony.PSX
{ {
public partial class Octoshock public partial class Octoshock
{ {
public TraceBuffer Tracer { get; private set; } public TraceBuffer Tracer { get; private set; }
public static string TraceHeader = "R3000A: PC, machine code, mnemonic, operands, registers (GPRs, lo, hi, sr, cause, epc)"; public static string TraceHeader = "R3000A: PC, machine code, mnemonic, operands, registers (GPRs, lo, hi, sr, cause, epc)";
OctoshockDll.ShockCallback_Trace trace_cb; OctoshockDll.ShockCallback_Trace trace_cb;
public void ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis) public void ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis)
{ {
var regs = GetCpuFlagsAndRegisters(); var regs = GetCpuFlagsAndRegisters();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
foreach (var r in regs) foreach (var r in regs)
{ {
if (r.Key != "pc") if (r.Key != "pc")
sb.Append( sb.Append(
string.Format("{0}:{1} ", string.Format("{0}:{1} ",
r.Key, r.Key,
r.Value.Value.ToHexString(r.Value.BitSize / 4))); r.Value.Value.ToHexString(r.Value.BitSize / 4)));
} }
Tracer.Put(new TraceInfo Tracer.Put(new TraceInfo
{ {
Disassembly = string.Format("{0:X8}: {1:X8} {2}", PC, inst, dis.PadRight(30)), Disassembly = string.Format("{0:X8}: {1:X8} {2}", PC, inst, dis.PadRight(30)),
RegisterInfo = sb.ToString().Trim() RegisterInfo = sb.ToString().Trim()
}); });
} }
private void ConnectTracer() private void ConnectTracer()
{ {
trace_cb = new OctoshockDll.ShockCallback_Trace(ShockTraceCallback); trace_cb = new OctoshockDll.ShockCallback_Trace(ShockTraceCallback);
Tracer = new TraceBuffer() { Header = TraceHeader }; Tracer = new TraceBuffer() { Header = TraceHeader };
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer); (ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
} }
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +1,114 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
//todo - be able to run out of PATH too //todo - be able to run out of PATH too
namespace BizHawk.Bizware.BizwareGL namespace BizHawk.Bizware.BizwareGL
{ {
public class CGC public class CGC
{ {
public CGC() public CGC()
{ {
}
public static string CGCBinPath;
private static string[] Escape(IEnumerable<string> args)
{
return args.Select(s => s.Contains(" ") ? string.Format("\"{0}\"", s) : s).ToArray();
}
public class Results
{
public bool Succeeded;
public string Code, Errors;
public Dictionary<string, string> MapCodeToNative = new Dictionary<string, string>();
public Dictionary<string, string> MapNativeToCode = new Dictionary<string, string>();
} }
Regex rxHlslSamplerCrashWorkaround = new Regex(@"\((.*?)(in sampler2D)(.*?)\)", RegexOptions.Multiline | RegexOptions.IgnoreCase); public static string CGCBinPath;
public Results Run(string code, string entry, string profile, bool hlslHacks) private static string[] Escape(IEnumerable<string> args)
{ {
//version=110; GLSL generates old fashioned semantic attributes and not generic attributes return args.Select(s => s.Contains(" ") ? string.Format("\"{0}\"", s) : s).ToArray();
string[] args = new[]{"-profile", profile, "-entry", entry, "-po", "version=110"}; }
args = Escape(args); public class Results
StringBuilder sbCmdline = new StringBuilder(); {
for (int i = 0; i < args.Length; i++) public bool Succeeded;
{ public string Code, Errors;
sbCmdline.Append(args[i]); public Dictionary<string, string> MapCodeToNative = new Dictionary<string, string>();
if (i != args.Length - 1) sbCmdline.Append(' '); public Dictionary<string, string> MapNativeToCode = new Dictionary<string, string>();
} }
//http://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why Regex rxHlslSamplerCrashWorkaround = new Regex(@"\((.*?)(in sampler2D)(.*?)\)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
using (Process proc = new Process())
{ public Results Run(string code, string entry, string profile, bool hlslHacks)
proc.StartInfo.UseShellExecute = false; {
proc.StartInfo.CreateNoWindow = true; //version=110; GLSL generates old fashioned semantic attributes and not generic attributes
proc.StartInfo.RedirectStandardInput = true; string[] args = new[]{"-profile", profile, "-entry", entry, "-po", "version=110"};
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true; args = Escape(args);
proc.StartInfo.Arguments = sbCmdline.ToString(); StringBuilder sbCmdline = new StringBuilder();
proc.StartInfo.FileName = CGCBinPath; for (int i = 0; i < args.Length; i++)
{
StringBuilder output = new StringBuilder(), error = new StringBuilder(); sbCmdline.Append(args[i]);
if (i != args.Length - 1) sbCmdline.Append(' ');
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) }
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{ //http://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why
proc.OutputDataReceived += (sender, e) => using (Process proc = new Process())
{ {
if (e.Data == null) outputWaitHandle.Set(); proc.StartInfo.UseShellExecute = false;
else output.AppendLine(e.Data); proc.StartInfo.CreateNoWindow = true;
}; proc.StartInfo.RedirectStandardInput = true;
proc.ErrorDataReceived += (sender, e) => proc.StartInfo.RedirectStandardOutput = true;
{ proc.StartInfo.RedirectStandardError = true;
if (e.Data == null) errorWaitHandle.Set(); proc.StartInfo.Arguments = sbCmdline.ToString();
else error.AppendLine(e.Data); proc.StartInfo.FileName = CGCBinPath;
};
StringBuilder output = new StringBuilder(), error = new StringBuilder();
proc.Start(); using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
new Thread(() => using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{ {
proc.StandardInput.AutoFlush = true; proc.OutputDataReceived += (sender, e) =>
proc.StandardInput.Write(code); {
proc.StandardInput.Flush(); if (e.Data == null) outputWaitHandle.Set();
proc.StandardInput.Close(); else output.AppendLine(e.Data);
}).Start(); };
proc.ErrorDataReceived += (sender, e) =>
proc.BeginOutputReadLine(); {
proc.BeginErrorReadLine(); if (e.Data == null) errorWaitHandle.Set();
proc.WaitForExit(); else error.AppendLine(e.Data);
outputWaitHandle.WaitOne(); };
errorWaitHandle.WaitOne();
}
proc.Start();
bool ok = (proc.ExitCode == 0); new Thread(() =>
{
var ret = new Results() proc.StandardInput.AutoFlush = true;
{ proc.StandardInput.Write(code);
Succeeded = ok, proc.StandardInput.Flush();
Code = output.ToString(), proc.StandardInput.Close();
Errors = error.ToString() }).Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
outputWaitHandle.WaitOne();
errorWaitHandle.WaitOne();
}
bool ok = (proc.ExitCode == 0);
var ret = new Results()
{
Succeeded = ok,
Code = output.ToString(),
Errors = error.ToString()
}; };
if (!ok) if (!ok)
Console.WriteLine(ret.Errors); Console.WriteLine(ret.Errors);
if (hlslHacks) if (hlslHacks)
{ {
ret.Code = rxHlslSamplerCrashWorkaround.Replace(ret.Code, m => string.Format("({0}uniform sampler2D{1})", m.Groups[1].Value, m.Groups[3].Value)); ret.Code = rxHlslSamplerCrashWorkaround.Replace(ret.Code, m => string.Format("({0}uniform sampler2D{1})", m.Groups[1].Value, m.Groups[3].Value));
} }
//make variable name map //make variable name map
//loop until the first line that doesnt start with a comment //loop until the first line that doesnt start with a comment
var reader = new StringReader(ret.Code); var reader = new StringReader(ret.Code);
for(;;) for(;;)
@ -131,10 +131,10 @@ namespace BizHawk.Bizware.BizwareGL
ret.MapCodeToNative[code_name] = native_name; ret.MapCodeToNative[code_name] = native_name;
ret.MapNativeToCode[native_name] = code_name; ret.MapNativeToCode[native_name] = code_name;
} }
} }
return ret; return ret;
} }
} }
} }
} }

View File

@ -1,46 +1,46 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using OpenTK; using OpenTK;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
namespace BizHawk.Bizware.BizwareGL namespace BizHawk.Bizware.BizwareGL
{ {
/// <summary> /// <summary>
/// Handles RetroArch's GLSL shader pass format /// Handles RetroArch's GLSL shader pass format
/// </summary> /// </summary>
public class RetroShader : IDisposable public class RetroShader : IDisposable
{ {
//NOTE: we may need to overhaul uniform-setting infrastructure later. //NOTE: we may need to overhaul uniform-setting infrastructure later.
//maybe samplers will need to be set by index and not by name (I think the specs dont dictate what the sampler must be named) //maybe samplers will need to be set by index and not by name (I think the specs dont dictate what the sampler must be named)
public RetroShader(IGL owner, string source, bool debug = false) public RetroShader(IGL owner, string source, bool debug = false)
{ {
Owner = owner; Owner = owner;
VertexLayout = owner.CreateVertexLayout(); VertexLayout = owner.CreateVertexLayout();
VertexLayout.DefineVertexAttribute("position", 0, 4, VertexAttribPointerType.Float, AttributeUsage.Position, false, 40, 0); VertexLayout.DefineVertexAttribute("position", 0, 4, VertexAttribPointerType.Float, AttributeUsage.Position, false, 40, 0);
VertexLayout.DefineVertexAttribute("color", 1, 4, VertexAttribPointerType.Float, AttributeUsage.Color0, false, 40, 16); //just dead weight, i have no idea why this is here. but some old HLSL compilers (used in bizhawk for various reasons) will want it to exist here since it exists in the vertex shader VertexLayout.DefineVertexAttribute("color", 1, 4, VertexAttribPointerType.Float, AttributeUsage.Color0, false, 40, 16); //just dead weight, i have no idea why this is here. but some old HLSL compilers (used in bizhawk for various reasons) will want it to exist here since it exists in the vertex shader
VertexLayout.DefineVertexAttribute("texCoord1", 2, 2, VertexAttribPointerType.Float, AttributeUsage.Texcoord0, false, 40, 32); VertexLayout.DefineVertexAttribute("texCoord1", 2, 2, VertexAttribPointerType.Float, AttributeUsage.Texcoord0, false, 40, 32);
VertexLayout.Close(); VertexLayout.Close();
string defines = "#define TEXCOORD TEXCOORD0\r\n"; //maybe not safe.. string defines = "#define TEXCOORD TEXCOORD0\r\n"; //maybe not safe..
string vsSource = "#define VERTEX\r\n" + defines + source; string vsSource = "#define VERTEX\r\n" + defines + source;
string psSource = "#define FRAGMENT\r\n" + defines + source; string psSource = "#define FRAGMENT\r\n" + defines + source;
var vs = owner.CreateVertexShader(true, vsSource, "main_vertex", debug); var vs = owner.CreateVertexShader(true, vsSource, "main_vertex", debug);
var ps = owner.CreateFragmentShader(true, psSource, "main_fragment", debug); var ps = owner.CreateFragmentShader(true, psSource, "main_fragment", debug);
Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, debug, "retro"); Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, debug, "retro");
if (!Pipeline.Available) if (!Pipeline.Available)
{ {
Available = false; Available = false;
return; return;
} }
//retroarch shaders will sometimes not have the right sampler name //retroarch shaders will sometimes not have the right sampler name
//it's unclear whether we should bind to s_p or sampler0 //it's unclear whether we should bind to s_p or sampler0
//lets bind to sampler0 in case we dont have s_p //lets bind to sampler0 in case we dont have s_p
sampler0 = Pipeline.TryGetUniform("s_p"); sampler0 = Pipeline.TryGetUniform("s_p");
if (sampler0 == null) if (sampler0 == null)
{ {
@ -58,80 +58,80 @@ namespace BizHawk.Bizware.BizwareGL
if (sampler0 == null) if (sampler0 == null)
return; return;
Available = true; Available = true;
} }
public bool Available { get; private set; } public bool Available { get; private set; }
public string Errors { get { return Pipeline.Errors; } } public string Errors { get { return Pipeline.Errors; } }
PipelineUniform sampler0; PipelineUniform sampler0;
public void Dispose() public void Dispose()
{ {
Pipeline.Dispose(); Pipeline.Dispose();
} }
public void Bind() public void Bind()
{ {
//lame... //lame...
Owner.BindPipeline(Pipeline); Owner.BindPipeline(Pipeline);
} }
public unsafe void Run(Texture2d tex, Size InputSize, Size OutputSize, bool flip) public unsafe void Run(Texture2d tex, Size InputSize, Size OutputSize, bool flip)
{ {
flip = false; flip = false;
//test //test
//ack! make sure to set the pipeline before setting uniforms //ack! make sure to set the pipeline before setting uniforms
Bind(); Bind();
Pipeline["IN.video_size"].Set(new Vector2(InputSize.Width, InputSize.Height)); Pipeline["IN.video_size"].Set(new Vector2(InputSize.Width, InputSize.Height));
Pipeline["IN.texture_size"].Set(new Vector2(tex.Width, tex.Height)); Pipeline["IN.texture_size"].Set(new Vector2(tex.Width, tex.Height));
Pipeline["IN.output_size"].Set(new Vector2(OutputSize.Width, OutputSize.Height)); Pipeline["IN.output_size"].Set(new Vector2(OutputSize.Width, OutputSize.Height));
Pipeline["IN.frame_count"].Set(1); //todo Pipeline["IN.frame_count"].Set(1); //todo
Pipeline["IN.frame_direction"].Set(1); //todo Pipeline["IN.frame_direction"].Set(1); //todo
var Projection = Owner.CreateGuiProjectionMatrix(OutputSize); var Projection = Owner.CreateGuiProjectionMatrix(OutputSize);
var Modelview = Owner.CreateGuiViewMatrix(OutputSize); var Modelview = Owner.CreateGuiViewMatrix(OutputSize);
var mat = Modelview * Projection; var mat = Modelview * Projection;
mat.Transpose(); mat.Transpose();
Pipeline["modelViewProj"].Set(mat, true); Pipeline["modelViewProj"].Set(mat, true);
Owner.SetTextureWrapMode(tex, true); Owner.SetTextureWrapMode(tex, true);
sampler0.Set(tex); sampler0.Set(tex);
Owner.SetViewport(OutputSize); Owner.SetViewport(OutputSize);
int w = OutputSize.Width; int w = OutputSize.Width;
int h = OutputSize.Height; int h = OutputSize.Height;
float v0,v1; float v0,v1;
if (flip) { v0 = 1; v1 = 0; } if (flip) { v0 = 1; v1 = 0; }
else { v0 = 0; v1 = 1; } else { v0 = 0; v1 = 1; }
float* pData = stackalloc float[10*4]; float* pData = stackalloc float[10*4];
int i=0; int i=0;
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topleft vert pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topleft vert
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color
pData[i++] = 0; pData[i++] = v0; pData[i++] = 0; pData[i++] = v0;
pData[i++] = w; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topright vert pData[i++] = w; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topright vert
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color
pData[i++] = 1; pData[i++] = v0; pData[i++] = 1; pData[i++] = v0;
pData[i++] = 0; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomleft vert pData[i++] = 0; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomleft vert
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color
pData[i++] = 0; pData[i++] = v1; pData[i++] = 0; pData[i++] = v1;
pData[i++] = w; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomright vert pData[i++] = w; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomright vert
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color
pData[i++] = 1; pData[i++] = v1; pData[i++] = 1; pData[i++] = v1;
Owner.SetBlendState(Owner.BlendNoneCopy); Owner.SetBlendState(Owner.BlendNoneCopy);
Owner.BindArrayData(pData); Owner.BindArrayData(pData);
Owner.DrawArrays(PrimitiveType.TriangleStrip, 0, 4); Owner.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
} }
public IGL Owner { get; private set; } public IGL Owner { get; private set; }
VertexLayout VertexLayout; VertexLayout VertexLayout;
public Pipeline Pipeline; public Pipeline Pipeline;
} }
} }