diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs
index 057ec89c0b..2603fd3329 100644
--- a/BizHawk.Client.Common/config/Config.cs
+++ b/BizHawk.Client.Common/config/Config.cs
@@ -509,6 +509,8 @@ namespace BizHawk.Client.Common
// TAStudio
public TasStateManagerSettings DefaultTasProjSettings = new TasStateManagerSettings();
+ /// defaults to 0 (GDI) - on linux this is forced to GDI+ later on
+ public int TasStudioRenderer = 0;
// Macro Tool
public RecentFiles RecentMacros = new RecentFiles(8);
diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
index 3b94629eba..ce2464e823 100644
--- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
+++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
@@ -592,6 +592,14 @@
InputRoll.cs
Component
+
+ InputRoll.cs
+ Component
+
+
+ InputRoll.cs
+ Component
+
Component
diff --git a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDI.cs b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDI.cs
new file mode 100644
index 0000000000..c3d6f0d471
--- /dev/null
+++ b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDI.cs
@@ -0,0 +1,433 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+
+using BizHawk.Client.EmuHawk.CustomControls;
+
+namespace BizHawk.Client.EmuHawk
+{
+ /// GDI32.dll related methods are abstracted to here
+ public partial class InputRoll
+ {
+ private readonly GDIRenderer _gdi;
+ private readonly IntPtr _rotatedFont;
+ private readonly IntPtr _normalFont;
+ private Size _charSize;
+
+ #region Initialization and Destruction
+
+ /// Initialises GDI-related stuff (called from constructor)
+ private void GDIConstruction()
+ {
+ using (var g = CreateGraphics()) using (_gdi.LockGraphics(g))
+ _charSize = _gdi.MeasureString("A", _commonFont); //TODO make this a property so changing it updates other values
+ }
+
+ private void GDIDispose()
+ {
+ _gdi.Dispose();
+ GDIRenderer.DestroyHFont(_normalFont);
+ GDIRenderer.DestroyHFont(_rotatedFont);
+ }
+
+ #endregion
+
+ #region Drawing Methods Using GDI
+
+ private void GDI_OnPaint(PaintEventArgs e)
+ {
+ using (_gdi.LockGraphics(e.Graphics))
+ {
+ _gdi.StartOffScreenBitmap(Width, Height);
+
+ // White Background
+ _gdi.SetBrush(Color.White);
+ _gdi.SetSolidPen(Color.White);
+ _gdi.FillRectangle(0, 0, Width, Height);
+
+ // Lag frame calculations
+ SetLagFramesArray();
+
+ var visibleColumns = _columns.VisibleColumns.ToList();
+
+ if (visibleColumns.Count != 0)
+ {
+ DrawColumnBg(e, visibleColumns);
+ DrawColumnText(e, visibleColumns);
+ }
+
+ // Background
+ DrawBg(e, visibleColumns);
+
+ // Foreground
+ DrawData(e, visibleColumns);
+
+ DrawColumnDrag(e);
+ DrawCellDrag(e);
+
+ _gdi.CopyToScreen();
+ _gdi.EndOffScreenBitmap();
+ }
+ }
+
+ private void GDI_DrawColumnDrag()
+ {
+ if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
+ {
+ var x1 = _currentX.Value - _columnDown.Width.Value / 2;
+ var y1 = _currentY.Value - CellHeight / 2;
+ var x2 = x1 + _columnDown.Width.Value;
+ var y2 = y1 + CellHeight;
+
+ _gdi.SetSolidPen(_backColor);
+ _gdi.DrawRectangle(x1, y1, x2, y2);
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+ _gdi.DrawString(_columnDown.Text, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding));
+ }
+ }
+
+ private void GDI_DrawCellDrag()
+ {
+ if (_draggingCell == null) return;
+
+ var rowIndex = _draggingCell.RowIndex.Value;
+ var column = _draggingCell.Column;
+ var text = "";
+ var offsetX = 0;
+ var offsetY = 0;
+ QueryItemText?.Invoke(rowIndex, column, out text, ref offsetX, ref offsetY);
+
+ var bgColor = _backColor;
+ QueryItemBkColor?.Invoke(rowIndex, column, ref bgColor);
+
+ var draggedWidth = column.Width.Value;
+ var draggedHeight = CellHeight;
+ var x1 = _currentX.Value - draggedWidth / 2;
+ var y1 = _currentY.Value - draggedHeight / 2;
+
+ _gdi.SetBrush(bgColor);
+ _gdi.FillRectangle(x1, y1, draggedWidth, draggedHeight);
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+ _gdi.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
+ }
+
+ private void GDI_DrawColumnText(IEnumerable visibleColumns)
+ {
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+ var isHoveringOnColumnCell = IsHoveringOnColumnCell;
+ if (HorizontalOrientation)
+ {
+ var start = -_vBar.Value;
+ foreach (var column in visibleColumns)
+ {
+ var point = new Point(CellWidthPadding, start + CellHeightPadding);
+ if (isHoveringOnColumnCell && column == CurrentCell.Column)
+ {
+ _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
+ _gdi.DrawString(column.Text, point);
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+ }
+ else
+ {
+ _gdi.DrawString(column.Text, point);
+ }
+ start += CellHeight;
+ }
+ }
+ else
+ {
+ var paddingX = 2 * CellWidthPadding - _hBar.Value; //TODO fix this CellPadding issue (2 * CellPadding vs just CellPadding)
+ foreach (var column in visibleColumns)
+ {
+ var point = new Point(column.Left.Value + paddingX, CellHeightPadding);
+ if (isHoveringOnColumnCell && column == CurrentCell.Column)
+ {
+ _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
+ _gdi.DrawString(column.Text, point);
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+ }
+ else
+ {
+ _gdi.DrawString(column.Text, point);
+ }
+ }
+ }
+ }
+
+ private void GDI_DrawData(IReadOnlyList visibleColumns)
+ {
+ if (visibleColumns.Count == 0) return; // Prevent exceptions with small TAStudio windows
+ if (QueryItemText == null) return;
+
+ _gdi.PrepDrawString(_normalFont, _foreColor);
+
+ var startRow = FirstVisibleRow;
+ var range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
+ int LastVisible;
+ if (HorizontalOrientation)
+ {
+ for (int i = 0, f = 0; f < range; i++, f++)
+ {
+ f += _lagFrames[i];
+ LastVisible = LastVisibleColumnIndex;
+ for (var j = FirstVisibleColumn; j <= LastVisible; j++)
+ {
+ Bitmap image = null;
+ var bitmapOffsetX = 0;
+ var bitmapOffsetY = 0;
+ QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
+
+ if (image != null)
+ {
+ _gdi.DrawBitmap(
+ image,
+ new Point(RowsToPixels(i) + CellWidthPadding + bitmapOffsetX, j * CellHeight + CellHeightPadding * 2 + bitmapOffsetY),
+ true
+ );
+ }
+
+ string text;
+ var strOffsetX = 0;
+ var strOffsetY = 0;
+ QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
+
+ var rePrep = j == 1;
+ if (rePrep)
+ {
+ // 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
+ _gdi.PrepDrawString(
+ _rotatedFont,
+ _selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow })
+ ? SystemColors.HighlightText
+ : _foreColor
+ );
+ }
+
+ // Centre Text
+ var point = new Point(
+ RowsToPixels(i) + (CellWidth - text.Length * _charSize.Width) / 2 + strOffsetX,
+ j * CellHeight + CellHeightPadding - _vBar.Value + strOffsetY
+ );
+ if (!string.IsNullOrWhiteSpace(text)) _gdi.DrawString(text, point);
+
+ if (rePrep) _gdi.PrepDrawString(_normalFont, _foreColor);
+ }
+ }
+ }
+ else
+ {
+ var xPadding = CellWidthPadding + 1 - _hBar.Value;
+ for (int i = 0, f = 0; f < range; i++, f++) // Vertical
+ {
+ f += _lagFrames[i];
+ LastVisible = LastVisibleColumnIndex;
+ var y = RowsToPixels(i) + CellHeightPadding;
+ for (var j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
+ {
+ var column = visibleColumns[j];
+ var x = column.Left.Value + xPadding;
+ Bitmap image = null;
+ var bitmapOffsetX = 0;
+ var bitmapOffsetY = 0;
+ QueryItemIcon?.Invoke(f + startRow, column, ref image, ref bitmapOffsetX, ref bitmapOffsetY);
+
+ if (image != null)
+ {
+ _gdi.DrawBitmap(
+ image,
+ new Point(x + bitmapOffsetX, y + bitmapOffsetY + CellHeightPadding),
+ true
+ );
+ }
+
+ string text;
+ var strOffsetX = 0;
+ var strOffsetY = 0;
+ QueryItemText(f + startRow, column, out text, ref strOffsetX, ref strOffsetY);
+
+ var rePrep = !_selectedItems.Contains(new Cell { Column = column, RowIndex = f + startRow });
+
+ if (rePrep) _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
+
+ if (!string.IsNullOrWhiteSpace(text)) _gdi.DrawString(text, new Point(x + strOffsetX, y + strOffsetY));
+
+ if (rePrep) _gdi.PrepDrawString(_normalFont, _foreColor);
+ }
+ }
+ }
+ }
+
+ private void GDI_DrawColumnBg(IReadOnlyList visibleColumns)
+ {
+ var columnCount = visibleColumns.Count;
+
+ _gdi.SetBrush(SystemColors.ControlLight);
+ _gdi.SetSolidPen(Color.Black);
+
+ if (HorizontalOrientation)
+ {
+ _gdi.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
+ _gdi.Line(0, 0, 0, columnCount * CellHeight + 1);
+ _gdi.Line(ColumnWidth, 0, ColumnWidth, columnCount * CellHeight + 1);
+
+ if (columnCount != 0) for (int i = 0, y = -_vBar.Value; i <= columnCount; i++, y += CellHeight)
+ {
+ _gdi.Line(1, y, ColumnWidth, y);
+ }
+ }
+ else
+ {
+ var bottomEdge = RowsToPixels(0);
+
+ // Gray column box and black line underneath
+ _gdi.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
+ _gdi.Line(0, 0, TotalColWidth.Value + 1, 0);
+ _gdi.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
+
+ // Vertical black seperators
+ foreach (var column in visibleColumns)
+ {
+ var x = column.Left.Value - _hBar.Value;
+ _gdi.Line(x, 0, x, bottomEdge);
+ }
+ if (columnCount != 0)
+ {
+ var x = TotalColWidth.Value - _hBar.Value;
+ _gdi.Line(x, 0, x, bottomEdge);
+ }
+ }
+
+ // Emphasis
+ var columnHeight = ColumnHeight - 1;
+ if (HorizontalOrientation)
+ {
+ for (var i = 0; i < columnCount; i++)
+ {
+ if (!visibleColumns[i].Emphasis) continue; // only act on emphasised columns
+
+ _gdi.SetBrush(SystemColors.ActiveBorder);
+ _gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, columnHeight);
+ }
+ }
+ else
+ {
+ foreach (var column in visibleColumns)
+ {
+ if (!column.Emphasis) continue; // only act on emphasised columns
+
+ _gdi.SetBrush(SystemColors.ActiveBorder);
+ _gdi.FillRectangle(column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, columnHeight);
+ }
+ }
+
+ // If the user is hovering over a column
+ if (IsHoveringOnColumnCell)
+ {
+ if (HorizontalOrientation)
+ {
+ for (var i = 0; i < columnCount; i++)
+ {
+ var column = visibleColumns[i];
+ if (column != CurrentCell.Column) continue; // only act on selected
+
+ _gdi.SetBrush(column.Emphasis ? Add(SystemColors.Highlight, 0x00222222) : SystemColors.Highlight);
+ _gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, columnHeight);
+ }
+ }
+ else
+ {
+ //TODO multiple selected columns
+ foreach (var column in visibleColumns)
+ {
+ if (column != CurrentCell.Column) continue; // only act on selected
+ if (column.Left.Value - _hBar.Value > Width || column.Right.Value - _hBar.Value < 0) continue; // Left of column is to the right of the viewable area, or right of column is to the left of the viewable area
+
+ _gdi.SetBrush(column.Emphasis ? Add(SystemColors.Highlight, 0x00550000) : SystemColors.Highlight);
+ var left = column.Left.Value + 1;
+ _gdi.FillRectangle(left - _hBar.Value, 1, column.Right.Value - left, columnHeight);
+ }
+ }
+ }
+ }
+
+ private void GDI_DrawBg(PaintEventArgs e, List visibleColumns)
+ {
+ if (UseCustomBackground && QueryItemBkColor != null) DoBackGroundCallback(e, visibleColumns);
+
+ if (GridLines)
+ {
+ _gdi.SetSolidPen(SystemColors.ControlLight);
+ if (HorizontalOrientation)
+ {
+ // Columns
+ var iLimit = VisibleRows + 1;
+ for (var i = 1; i < iLimit; i++)
+ {
+ var x = RowsToPixels(i);
+ _gdi.Line(x, 1, x, DrawHeight);
+ }
+
+ // Rows
+ var x1 = RowsToPixels(0) + 1;
+ var jLimit = visibleColumns.Count + 1;
+ for (var j = 0; j < jLimit; j++) _gdi.Line(x1, j * CellHeight - _vBar.Value, DrawWidth, j * CellHeight - _vBar.Value);
+ }
+ else
+ {
+ // Columns
+ var y1 = ColumnHeight + 1;
+ var y2 = Height - 1;
+ foreach (var column in visibleColumns)
+ {
+ var x = column.Left.Value - _hBar.Value;
+ _gdi.Line(x, y1, x, y2);
+ }
+ if (visibleColumns.Count != 0)
+ {
+ var x = TotalColWidth.Value - _hBar.Value;
+ _gdi.Line(x, y1, x, y2);
+ }
+
+ // Rows
+ var x2 = Width + 1;
+ var iLimit = VisibleRows + 1;
+ for (var i = 1; i < iLimit; i++)
+ {
+ var y = RowsToPixels(i);
+ _gdi.Line(0, y, x2, y);
+ }
+ }
+ }
+
+ if (_selectedItems.Count != 0) DoSelectionBG(e, visibleColumns);
+ }
+
+ private void GDI_DrawCellBG(Color color, Cell cell, IList visibleColumns)
+ {
+ // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
+ int x, y, w;
+ if (HorizontalOrientation)
+ {
+ x = RowsToPixels(cell.RowIndex.Value) + 1;
+ if (x < ColumnWidth) return;
+ y = CellHeight * visibleColumns.IndexOf(cell.Column) + 1 - _vBar.Value;
+ w = CellWidth - 1;
+ }
+ else
+ {
+ y = RowsToPixels(cell.RowIndex.Value) + 1;
+ if (y < ColumnHeight) return;
+ x = cell.Column.Left.Value - _hBar.Value + 1;
+ w = cell.Column.Width.Value - 1;
+ }
+ if (x > DrawWidth || y > DrawHeight) return; // Don't draw if off-screen.
+
+ _gdi.SetBrush(color);
+ _gdi.FillRectangle(x, y, w, CellHeight - 1);
+ }
+
+ #endregion
+ }
+}
diff --git a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDIP.cs b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDIP.cs
new file mode 100644
index 0000000000..8137ff9e1b
--- /dev/null
+++ b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.GDIP.cs
@@ -0,0 +1,477 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace BizHawk.Client.EmuHawk
+{
+ /// New GDI+ methods live here
+ public partial class InputRoll
+ {
+ /// instance field to mirror GDI implementation
+ private Pen sPen;
+
+ /// instance field to mirror GDI implementation
+ private Brush sBrush;
+
+ /// GDI+ uses floats to measure strings
+ private SizeF _charSizeF;
+
+ #region Initialization and Destruction
+
+ /// Initialises GDI+-related stuff (called from constructor)
+ private void GDIPConstruction()
+ {
+ // HFont?
+ // Rotated HFont?
+
+ SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ SetStyle(ControlStyles.UserPaint, true);
+ SetStyle(ControlStyles.SupportsTransparentBackColor, true);
+ SetStyle(ControlStyles.Opaque, true);
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+
+ using (var g = CreateGraphics())
+ {
+ _charSizeF = g.MeasureString("A", _commonFont);
+// _charSize = Size.Round(sizeF);
+ }
+ }
+
+ #endregion
+
+ #region Drawing Methods Using GDI+
+
+ private void GDIP_OnPaint(PaintEventArgs e)
+ {
+ // white background
+ sBrush = new SolidBrush(Color.White);
+ sPen = new Pen(Color.White);
+
+ e.Graphics.FillRectangle(sBrush, e.ClipRectangle);
+ e.Graphics.Flush();
+
+ // Lag frame calculations
+ SetLagFramesArray();
+
+ var visibleColumns = _columns.VisibleColumns.ToList();
+
+ if (visibleColumns.Count != 0)
+ {
+ DrawColumnBg(e, visibleColumns);
+ DrawColumnText(e, visibleColumns);
+ }
+
+ // Background
+ DrawBg(e, visibleColumns);
+
+ // Foreground
+ DrawData(e, visibleColumns);
+
+ DrawColumnDrag(e);
+ DrawCellDrag(e);
+ }
+
+ private void GDIP_DrawColumnDrag(PaintEventArgs e)
+ {
+ if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
+ {
+ var x1 = _currentX.Value - _columnDown.Width.Value / 2;
+ var y1 = _currentY.Value - CellHeight / 2;
+ var x2 = x1 + _columnDown.Width.Value;
+ var y2 = y1 + CellHeight;
+
+ sPen = new Pen(_backColor);
+ e.Graphics.DrawRectangle(sPen, x1, y1, x2, y2);
+ sBrush = new SolidBrush(_foreColor);
+// e.Graphics.DrawString(_columnDown.Text, _commonFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding, y1 + CellHeightPadding)));
+ GDIP_DrawString(e, _columnDown.Text, _commonFont, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding), _foreColor);
+ }
+ }
+
+ private void GDIP_DrawCellDrag(PaintEventArgs e)
+ {
+ if (_draggingCell == null) return;
+
+ var text = "";
+ var offsetX = 0;
+ var offsetY = 0;
+ QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY);
+
+ var bgColor = _backColor;
+ QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor);
+
+ var x1 = _currentX.Value - _draggingCell.Column.Width.Value / 2;
+ var y1 = _currentY.Value - CellHeight / 2;
+ var x2 = x1 + _draggingCell.Column.Width.Value;
+ var y2 = y1 + CellHeight;
+
+ sBrush = new SolidBrush(bgColor);
+ e.Graphics.FillRectangle(sBrush, x1, y1, x2 - x1, y2 - y1);
+ sBrush = new SolidBrush(_foreColor);
+// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY)));
+ GDIP_DrawString(e, text, _commonFont, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY), _foreColor);
+ }
+
+ private void GDIP_DrawColumnText(PaintEventArgs e, IReadOnlyCollection visibleColumns)
+ {
+ sBrush = new SolidBrush(_foreColor);
+ if (HorizontalOrientation)
+ {
+ var start = -_vBar.Value;
+
+ foreach (var column in visibleColumns)
+ {
+ var point = new Point(CellWidthPadding, start + CellHeightPadding);
+
+ if (IsHoveringOnColumnCell && column == CurrentCell.Column)
+ {
+ var temp = sBrush;
+ sBrush = new SolidBrush(SystemColors.HighlightText);
+// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
+ GDIP_DrawString(e, column.Text, _commonFont, point, SystemColors.HighlightText);
+ sBrush = temp;
+ }
+ else
+ {
+// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
+ GDIP_DrawString(e, column.Text, _commonFont, point, _foreColor);
+ }
+
+ start += CellHeight;
+ }
+ }
+ else
+ {
+ var xPadding = CellWidthPadding + 1 - _hBar.Value;
+
+ foreach (var column in visibleColumns)
+ {
+ var point = new Point(column.Left.Value + xPadding, CellHeightPadding);
+
+ if (IsHoveringOnColumnCell && column == CurrentCell.Column)
+ {
+ var temp = sBrush;
+ sBrush = new SolidBrush(SystemColors.HighlightText);
+// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
+ GDIP_DrawString(e, column.Text, _commonFont, point, SystemColors.HighlightText);
+ sBrush = temp;
+ }
+ else
+ {
+// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
+ GDIP_DrawString(e, column.Text, _commonFont, point, _foreColor);
+ }
+ }
+ }
+ }
+
+ private void GDIP_DrawData(PaintEventArgs e, IReadOnlyList visibleColumns)
+ {
+ if (visibleColumns.Count == 0) return; // Prevent exceptions with small TAStudio windows
+ if (QueryItemText == null) return;
+
+ var startRow = FirstVisibleRow;
+ int LastVisible;
+ if (HorizontalOrientation)
+ {
+ var isRotated = false;
+ var fLimit = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
+
+ sBrush = new SolidBrush(_foreColor);
+ for (int i = 0, f = 0; f < fLimit; i++, f++)
+ {
+ f += _lagFrames[i];
+ LastVisible = LastVisibleColumnIndex;
+ for (var j = FirstVisibleColumn; j <= LastVisible; j++)
+ {
+ Bitmap image = null;
+ var bitmapOffsetX = 0;
+ var bitmapOffsetY = 0;
+ QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
+
+ if (image != null)
+ {
+ var x1 = RowsToPixels(i) + CellWidthPadding + bitmapOffsetX;
+ var y1 = j * CellHeight + CellHeightPadding * 2 + bitmapOffsetY;
+ e.Graphics.DrawImage(image, new Point(x1, y1));
+ }
+
+ string text;
+ var strOffsetX = 0;
+ var strOffsetY = 0;
+ QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
+
+ // Centre Text
+ var point = new Point(
+ RowsToPixels(i) + (CellWidth - (int)Math.Round(text.Length * _charSizeF.Width)) / 2 + strOffsetX,
+ j * CellHeight + CellHeightPadding - _vBar.Value + strOffsetY
+ );
+
+ var rePrep = false;
+ if (j == 1)
+ {
+ if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow }))
+ {
+ isRotated = true;
+ sBrush = new SolidBrush(SystemColors.HighlightText);
+ rePrep = true;
+ }
+ else if (j == 1)
+ {
+ // 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
+ rePrep = true;
+ isRotated = true;
+ sBrush = new SolidBrush(SystemColors.HighlightText);
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+// _gdi.DrawString(text, point);
+ if (isRotated)
+ {
+ var sz = e.Graphics.VisibleClipBounds.Size;
+ e.Graphics.TranslateTransform(sz.Width / 2, sz.Height / 2);
+ e.Graphics.RotateTransform(90);
+ sz = e.Graphics.MeasureString(text, _commonFont);
+ e.Graphics.DrawString(text, _commonFont, sBrush, -(sz.Width / 2), -(sz.Height / 2));
+ }
+ else
+ {
+// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)point);
+ GDIP_DrawString(e, text, _commonFont, point, new Pen(sBrush).Color);
+ }
+ }
+
+ if (rePrep)
+ {
+ isRotated = false;
+ sBrush = new SolidBrush(_foreColor);
+ }
+ }
+ }
+ }
+ else
+ {
+ var range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
+ var xPadding = CellWidthPadding + 1 - _hBar.Value;
+ sBrush = new SolidBrush(_foreColor);
+ for (int i = 0, f = 0; f < range; i++, f++) // Vertical
+ {
+ f += _lagFrames[i];
+ LastVisible = LastVisibleColumnIndex;
+ for (var j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
+ {
+ var col = visibleColumns[j];
+
+ Bitmap image = null;
+ var bitmapOffsetX = 0;
+ var bitmapOffsetY = 0;
+ QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
+
+ var point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding);
+ if (image != null) e.Graphics.DrawImage(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding));
+
+ string text;
+ var strOffsetX = 0;
+ var strOffsetY = 0;
+ QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
+
+ var rePrep = false;
+ if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow }))
+ {
+ sBrush = new SolidBrush(SystemColors.HighlightText);
+ rePrep = true;
+ }
+
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)(new Point(point.X + strOffsetX, point.Y + strOffsetY)));
+ GDIP_DrawString(e, text, _commonFont, new Point(point.X + strOffsetX, point.Y + strOffsetY), new Pen(sBrush).Color);
+ }
+
+ if (rePrep) sBrush = new SolidBrush(_foreColor);
+ }
+ }
+ }
+ }
+
+ private void GDIP_DrawColumnBg(PaintEventArgs e, IReadOnlyList visibleColumns)
+ {
+ var columnCount = visibleColumns.Count;
+ sBrush = new SolidBrush(SystemColors.ControlLight);
+ sPen = new Pen(Color.Black);
+
+ if (HorizontalOrientation)
+ {
+ e.Graphics.FillRectangle(sBrush, 0, 0, ColumnWidth + 1, DrawHeight + 1);
+ e.Graphics.DrawLine(sPen, 0, 0, 0, columnCount * CellHeight + 1);
+ e.Graphics.DrawLine(sPen, ColumnWidth, 0, ColumnWidth, columnCount * CellHeight + 1);
+
+ var iLimit = columnCount + 1;
+ if (iLimit > 1)
+ {
+ for (int i = 0, y = -_vBar.Value; i < iLimit; i++, y += CellHeight) e.Graphics.DrawLine(sPen, 1, y, ColumnWidth, y);
+ }
+ }
+ else
+ {
+ var bottomEdge = RowsToPixels(0);
+
+ // Gray column box and black line underneath
+ e.Graphics.FillRectangle(sBrush, 0, 0, Width + 1, bottomEdge + 1);
+ e.Graphics.DrawLine(sPen, 0, 0, TotalColWidth.Value + 1, 0);
+ e.Graphics.DrawLine(sPen, 0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
+
+ // Vertical black seperators
+ foreach (var column in visibleColumns)
+ {
+ var pos = column.Left.Value - _hBar.Value;
+ e.Graphics.DrawLine(sPen, pos, 0, pos, bottomEdge);
+ }
+ if (columnCount != 0)
+ {
+ var right = TotalColWidth.Value - _hBar.Value;
+ e.Graphics.DrawLine(sPen, right, 0, right, bottomEdge);
+ }
+ }
+
+ // Emphasis
+ for (var i = 0; i < columnCount; i++)
+ {
+ var column = visibleColumns[i];
+ if (!column.Emphasis) continue; // only act on emphasised columns
+
+ sBrush = new SolidBrush(SystemColors.ActiveBorder);
+ if (HorizontalOrientation) e.Graphics.FillRectangle(sBrush, 1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
+ else e.Graphics.FillRectangle(sBrush, column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
+ }
+
+ // If the user is hovering over a column
+ if (IsHoveringOnColumnCell)
+ {
+ if (HorizontalOrientation)
+ {
+ for (var i = 0; i < columnCount; i++)
+ {
+ var column = visibleColumns[i];
+ if (column != CurrentCell.Column) continue; // only act on selected
+
+ sBrush = new SolidBrush(column.Emphasis
+ ? Color.FromArgb(SystemColors.Highlight.ToArgb() + 0x00222222) //TODO should be bitwise or?
+ : SystemColors.Highlight);
+
+ e.Graphics.FillRectangle(sBrush, 1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
+ }
+ }
+ else
+ {
+ //TODO multiple selected columns
+ foreach (var column in visibleColumns)
+ {
+ if (column != CurrentCell.Column) continue; // only act on selected
+ if (column.Left.Value - _hBar.Value > Width || column.Right.Value - _hBar.Value < 0) continue; // Left of column is to the right of the viewable area, or right of column is to the left of the viewable area
+
+ var left = column.Left.Value - _hBar.Value;
+ var width = column.Right.Value - _hBar.Value - left;
+ sBrush = new SolidBrush(column.Emphasis
+ ? Color.FromArgb(SystemColors.Highlight.ToArgb() + 0x00550000) //TODO should be bitwise or?
+ : SystemColors.Highlight);
+
+ e.Graphics.FillRectangle(sBrush, left + 1, 1, width - 1, ColumnHeight - 1);
+ }
+ }
+ }
+ }
+
+ private void GDIP_DrawBg(PaintEventArgs e, List visibleColumns)
+ {
+ if (UseCustomBackground && QueryItemBkColor != null) DoBackGroundCallback(e, visibleColumns);
+
+ if (GridLines)
+ {
+ sPen = new Pen(SystemColors.ControlLight);
+ if (HorizontalOrientation)
+ {
+ // Columns
+ var iLimit = VisibleRows + 1;
+ for (var i = 1; i < iLimit; i++)
+ {
+ var x = RowsToPixels(i);
+ e.Graphics.DrawLine(sPen, x, 1, x, DrawHeight);
+ }
+
+ // Rows
+ var x1 = RowsToPixels(0) + 1;
+ var jLimit = visibleColumns.Count + 1;
+ for (var j = 0; j < jLimit; j++)
+ {
+ var y = j * CellHeight - _vBar.Value;
+ e.Graphics.DrawLine(sPen, x1, y, DrawWidth, y);
+ }
+ }
+ else
+ {
+ // Columns
+ var y1 = ColumnHeight + 1;
+ var y2 = Height - 1;
+ foreach (var column in visibleColumns)
+ {
+ var x = column.Left.Value - _hBar.Value;
+ e.Graphics.DrawLine(sPen, x, y1, x, y2);
+ }
+ if (visibleColumns.Count != 0)
+ {
+ var x = TotalColWidth.Value - _hBar.Value;
+ e.Graphics.DrawLine(sPen, x, y1, x, y2);
+ }
+
+ // Rows
+ var x2 = Width + 1;
+ var iLimit = VisibleRows + 1;
+ for (var i = 1; i < iLimit; i++)
+ {
+ var y = RowsToPixels(i);
+ e.Graphics.DrawLine(sPen, 0, y, x2, y);
+ }
+ }
+ }
+
+ if (_selectedItems.Count != 0) DoSelectionBG(e, visibleColumns);
+ }
+
+ private void GDIP_DrawCellBG(PaintEventArgs e, Color color, Cell cell, IList visibleColumns)
+ {
+ // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
+ int x, y, w;
+ if (HorizontalOrientation)
+ {
+ x = RowsToPixels(cell.RowIndex.Value) + 1;
+ if (x < ColumnWidth) return;
+ y = CellHeight * visibleColumns.IndexOf(cell.Column) + 1 - _vBar.Value;
+ w = CellWidth - 1;
+ }
+ else
+ {
+ y = RowsToPixels(cell.RowIndex.Value) + 1;
+ if (y < ColumnHeight) return;
+ x = cell.Column.Left.Value - _hBar.Value + 1;
+ w = cell.Column.Width.Value - 1;
+ }
+ if (x > DrawWidth || y > DrawHeight) return; // Don't draw if off-screen.
+
+ sBrush = new SolidBrush(color.A == 0 ? Color.FromArgb(255, color) : color);
+ e.Graphics.FillRectangle(sBrush, x, y, w, CellHeight - 1);
+ }
+
+ private void GDIP_DrawString(PaintEventArgs e, string text, Font font, Point point, Color color)
+ {
+// TextRenderer.DrawText(e.Graphics, text, font, point, color);
+ e.Graphics.DrawString(text, font, new SolidBrush(color), (PointF)point);
+ }
+
+ #endregion
+ }
+}
diff --git a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.cs b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.cs
index b5a2556f7b..452703033d 100644
--- a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.cs
+++ b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.cs
@@ -6,380 +6,59 @@ using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk
{
+ ///
+ /// This in the most part now contains renderer selection logic
+ ///
public partial class InputRoll
{
+ #region Renderer-Based Logic Methods
+
protected override void OnPaint(PaintEventArgs e)
{
- using (_gdi.LockGraphics(e.Graphics))
- {
- _gdi.StartOffScreenBitmap(Width, Height);
-
- // White Background
- _gdi.SetBrush(Color.White);
- _gdi.SetSolidPen(Color.White);
- _gdi.FillRectangle(0, 0, Width, Height);
-
- // Lag frame calculations
- SetLagFramesArray();
-
- var visibleColumns = _columns.VisibleColumns.ToList();
-
- if (visibleColumns.Any())
- {
- DrawColumnBg(e, visibleColumns);
- DrawColumnText(e, visibleColumns);
- }
-
- // Background
- DrawBg(e, visibleColumns);
-
- // Foreground
- DrawData(e, visibleColumns);
-
- DrawColumnDrag(e);
- DrawCellDrag(e);
-
- _gdi.CopyToScreen();
- _gdi.EndOffScreenBitmap();
- }
- }
-
- protected override void OnPaintBackground(PaintEventArgs pevent)
- {
- // Do nothing, and this should never be called
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_OnPaint(e);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_OnPaint(e);
}
private void DrawColumnDrag(PaintEventArgs e)
{
- if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
- {
- int x1 = _currentX.Value - (_columnDown.Width.Value / 2);
- int y1 = _currentY.Value - (CellHeight / 2);
- int x2 = x1 + _columnDown.Width.Value;
- int y2 = y1 + CellHeight;
-
- _gdi.SetSolidPen(_backColor);
- _gdi.DrawRectangle(x1, y1, x2, y2);
- _gdi.PrepDrawString(_normalFont, _foreColor);
- _gdi.DrawString(_columnDown.Text, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding));
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawColumnDrag(e);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawColumnDrag();
}
private void DrawCellDrag(PaintEventArgs e)
{
- if (_draggingCell != null)
- {
- var text = "";
- int offsetX = 0;
- int offsetY = 0;
- QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY);
-
- Color bgColor = _backColor;
- QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor);
-
- int x1 = _currentX.Value - (_draggingCell.Column.Width.Value / 2);
- int y1 = _currentY.Value - (CellHeight / 2);
- int x2 = x1 + _draggingCell.Column.Width.Value;
- int y2 = y1 + CellHeight;
-
-
- _gdi.SetBrush(bgColor);
- _gdi.FillRectangle(x1, y1, x2 - x1, y2 - y1);
- _gdi.PrepDrawString(_normalFont, _foreColor);
- _gdi.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawCellDrag(e);
+ else if (Renderer == RollRenderer.GDI)
+ GDIP_DrawCellDrag(e);
}
private void DrawColumnText(PaintEventArgs e, List visibleColumns)
{
- if (HorizontalOrientation)
- {
- int start = -_vBar.Value;
-
- _gdi.PrepDrawString(_normalFont, _foreColor);
-
- foreach (var column in visibleColumns)
- {
- var point = new Point(CellWidthPadding, start + CellHeightPadding);
-
- if (IsHoveringOnColumnCell && column == CurrentCell.Column)
- {
- _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
- _gdi.DrawString(column.Text, point);
- _gdi.PrepDrawString(_normalFont, _foreColor);
- }
- else
- {
- _gdi.DrawString(column.Text, point);
- }
-
- start += CellHeight;
- }
- }
- else
- {
- _gdi.PrepDrawString(_normalFont, _foreColor);
-
- foreach (var column in visibleColumns)
- {
- var point = new Point(column.Left.Value + 2 * CellWidthPadding - _hBar.Value, CellHeightPadding); // TODO: fix this CellPadding issue (2 * CellPadding vs just CellPadding)
-
- if (IsHoveringOnColumnCell && column == CurrentCell.Column)
- {
- _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
- _gdi.DrawString(column.Text, point);
- _gdi.PrepDrawString(_normalFont, _foreColor);
- }
- else
- {
- _gdi.DrawString(column.Text, point);
- }
- }
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawColumnText(e, visibleColumns);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawColumnText(visibleColumns);
}
private void DrawData(PaintEventArgs e, List visibleColumns)
{
- // Prevent exceptions with small TAStudio windows
- if (visibleColumns.Count == 0)
- {
- return;
- }
- if (QueryItemText != null)
- {
- if (HorizontalOrientation)
- {
- int startRow = FirstVisibleRow;
- int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
-
- _gdi.PrepDrawString(_normalFont, _foreColor);
- for (int i = 0, f = 0; f < range; i++, f++)
- {
- f += _lagFrames[i];
- int LastVisible = LastVisibleColumnIndex;
- for (int j = FirstVisibleColumn; j <= LastVisible; j++)
- {
- Bitmap image = null;
- int x = 0;
- int y = 0;
- int bitmapOffsetX = 0;
- int bitmapOffsetY = 0;
-
- QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
-
- if (image != null)
- {
- x = RowsToPixels(i) + CellWidthPadding + bitmapOffsetX;
- y = (j * CellHeight) + (CellHeightPadding * 2) + bitmapOffsetY;
- _gdi.DrawBitmap(image, new Point(x, y), true);
- }
-
- string text;
- int strOffsetX = 0;
- int strOffsetY = 0;
- QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
-
- // Center Text
- x = RowsToPixels(i) + ((CellWidth - (text.Length * _charSize.Width)) / 2);
- y = (j * CellHeight) + CellHeightPadding - _vBar.Value;
- var point = new Point(x + strOffsetX, y + strOffsetY);
-
- var rePrep = false;
- if (j == 1)
- if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow }))
- {
- _gdi.PrepDrawString(_rotatedFont, SystemColors.HighlightText);
- rePrep = true;
- }
- else if (j == 1)
- {
- // 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
- rePrep = true;
- _gdi.PrepDrawString(_rotatedFont, _foreColor);
- }
-
- if (!string.IsNullOrWhiteSpace(text))
- {
- _gdi.DrawString(text, point);
- }
-
- if (rePrep)
- {
- _gdi.PrepDrawString(_normalFont, _foreColor);
- }
- }
- }
- }
- else
- {
- int startRow = FirstVisibleRow;
- int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
-
- _gdi.PrepDrawString(_normalFont, _foreColor);
- int xPadding = CellWidthPadding + 1 - _hBar.Value;
- for (int i = 0, f = 0; f < range; i++, f++) // Vertical
- {
- f += _lagFrames[i];
- int LastVisible = LastVisibleColumnIndex;
- for (int j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
- {
- RollColumn col = visibleColumns[j];
-
- string text;
- int strOffsetX = 0;
- int strOffsetY = 0;
- Point point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding);
-
- Bitmap image = null;
- int bitmapOffsetX = 0;
- int bitmapOffsetY = 0;
-
- QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
-
- if (image != null)
- {
- _gdi.DrawBitmap(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding), true);
- }
-
- QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
-
- bool rePrep = false;
- if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow }))
- {
- _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
- rePrep = true;
- }
-
- if (!string.IsNullOrWhiteSpace(text))
- {
- _gdi.DrawString(text, new Point(point.X + strOffsetX, point.Y + strOffsetY));
- }
-
- if (rePrep)
- {
- _gdi.PrepDrawString(_normalFont, _foreColor);
- }
- }
- }
- }
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawData(e, visibleColumns);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawData(visibleColumns);
}
private void DrawColumnBg(PaintEventArgs e, List visibleColumns)
{
- _gdi.SetBrush(SystemColors.ControlLight);
- _gdi.SetSolidPen(Color.Black);
-
- if (HorizontalOrientation)
- {
- _gdi.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
- _gdi.Line(0, 0, 0, visibleColumns.Count * CellHeight + 1);
- _gdi.Line(ColumnWidth, 0, ColumnWidth, visibleColumns.Count * CellHeight + 1);
-
- int start = -_vBar.Value;
- foreach (var column in visibleColumns)
- {
- _gdi.Line(1, start, ColumnWidth, start);
- start += CellHeight;
- }
-
- if (visibleColumns.Any())
- {
- _gdi.Line(1, start, ColumnWidth, start);
- }
- }
- else
- {
- int bottomEdge = RowsToPixels(0);
-
- // Gray column box and black line underneath
- _gdi.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
- _gdi.Line(0, 0, TotalColWidth.Value + 1, 0);
- _gdi.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
-
- // Vertical black seperators
- for (int i = 0; i < visibleColumns.Count; i++)
- {
- int pos = visibleColumns[i].Left.Value - _hBar.Value;
- _gdi.Line(pos, 0, pos, bottomEdge);
- }
-
- // Draw right most line
- if (visibleColumns.Any())
- {
- int right = TotalColWidth.Value - _hBar.Value;
- _gdi.Line(right, 0, right, bottomEdge);
- }
- }
-
- // Emphasis
- foreach (var column in visibleColumns.Where(c => c.Emphasis))
- {
- _gdi.SetBrush(SystemColors.ActiveBorder);
- if (HorizontalOrientation)
- {
- _gdi.FillRectangle(1, visibleColumns.IndexOf(column) * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
- }
- else
- {
- _gdi.FillRectangle(column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
- }
- }
-
- // If the user is hovering over a column
- if (IsHoveringOnColumnCell)
- {
- if (HorizontalOrientation)
- {
- for (int i = 0; i < visibleColumns.Count; i++)
- {
- if (visibleColumns[i] != CurrentCell.Column)
- {
- continue;
- }
-
- if (CurrentCell.Column.Emphasis)
- {
- _gdi.SetBrush(Add(SystemColors.Highlight, 0x00222222));
- }
- else
- {
- _gdi.SetBrush(SystemColors.Highlight);
- }
-
- _gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
- }
- }
- else
- {
- // TODO multiple selected columns
- for (int i = 0; i < visibleColumns.Count; i++)
- {
- if (visibleColumns[i] == CurrentCell.Column)
- {
- // Left of column is to the right of the viewable area or right of column is to the left of the viewable area
- if (visibleColumns[i].Left.Value - _hBar.Value > Width || visibleColumns[i].Right.Value - _hBar.Value < 0)
- {
- continue;
- }
-
- int left = visibleColumns[i].Left.Value - _hBar.Value;
- int width = visibleColumns[i].Right.Value - _hBar.Value - left;
-
- if (CurrentCell.Column.Emphasis)
- {
- _gdi.SetBrush(Add(SystemColors.Highlight, 0x00550000));
- }
- else
- {
- _gdi.SetBrush(SystemColors.Highlight);
- }
-
- _gdi.FillRectangle(left + 1, 1, width - 1, ColumnHeight - 1);
- }
- }
- }
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawColumnBg(e, visibleColumns);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawColumnBg(visibleColumns);
}
// TODO refactor this and DoBackGroundCallback functions.
@@ -388,57 +67,30 @@ namespace BizHawk.Client.EmuHawk
///
private void DrawBg(PaintEventArgs e, List visibleColumns)
{
- if (UseCustomBackground && QueryItemBkColor != null)
- {
- DoBackGroundCallback(e, visibleColumns);
- }
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawBg(e, visibleColumns);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawBg(e, visibleColumns);
+ }
- if (GridLines)
- {
- _gdi.SetSolidPen(SystemColors.ControlLight);
- if (HorizontalOrientation)
- {
- // Columns
- for (int i = 1; i < VisibleRows + 1; i++)
- {
- int x = RowsToPixels(i);
- _gdi.Line(x, 1, x, DrawHeight);
- }
+ ///
+ /// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices.
+ ///
+ private void DrawCellBG(PaintEventArgs e, Color color, Cell cell, List visibleColumns)
+ {
+ if (Renderer == RollRenderer.GDIPlus)
+ GDIP_DrawCellBG(e, color, cell, visibleColumns);
+ else if (Renderer == RollRenderer.GDI)
+ GDI_DrawCellBG(color, cell, visibleColumns);
+ }
- // Rows
- for (int i = 0; i < visibleColumns.Count + 1; i++)
- {
- _gdi.Line(RowsToPixels(0) + 1, i * CellHeight - _vBar.Value, DrawWidth, i * CellHeight - _vBar.Value);
- }
- }
- else
- {
- // Columns
- int y = ColumnHeight + 1;
- int? totalColWidth = TotalColWidth;
- foreach (var column in visibleColumns)
- {
- int x = column.Left.Value - _hBar.Value;
- _gdi.Line(x, y, x, Height - 1);
- }
+ #endregion
- if (visibleColumns.Any())
- {
- _gdi.Line(totalColWidth.Value - _hBar.Value, y, totalColWidth.Value - _hBar.Value, Height - 1);
- }
+ #region Non-Renderer-Specific Methods
- // Rows
- for (int i = 1; i < VisibleRows + 1; i++)
- {
- _gdi.Line(0, RowsToPixels(i), Width + 1, RowsToPixels(i));
- }
- }
- }
-
- if (_selectedItems.Any())
- {
- DoSelectionBG(e, visibleColumns);
- }
+ protected override void OnPaintBackground(PaintEventArgs pevent)
+ {
+ // Do nothing, and this should never be called
}
private void DoSelectionBG(PaintEventArgs e, List visibleColumns)
@@ -484,49 +136,10 @@ namespace BizHawk.Client.EmuHawk
cellColor = Color.FromArgb(cellColor.R - (int)((cellColor.R - SystemColors.Highlight.R) * alpha),
cellColor.G - (int)((cellColor.G - SystemColors.Highlight.G) * alpha),
cellColor.B - (int)((cellColor.B - SystemColors.Highlight.B) * alpha));
- DrawCellBG(cellColor, relativeCell, visibleColumns);
+ DrawCellBG(e, cellColor, relativeCell, visibleColumns);
}
}
- ///
- /// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices.
- ///
- private void DrawCellBG(Color color, Cell cell, List visibleColumns)
- {
- int x, y, w, h;
-
- if (HorizontalOrientation)
- {
- x = RowsToPixels(cell.RowIndex.Value) + 1;
- w = CellWidth - 1;
- y = (CellHeight * visibleColumns.IndexOf(cell.Column)) + 1 - _vBar.Value; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
- h = CellHeight - 1;
- if (x < ColumnWidth)
- {
- return;
- }
- }
- else
- {
- w = cell.Column.Width.Value - 1;
- x = cell.Column.Left.Value - _hBar.Value + 1;
- y = RowsToPixels(cell.RowIndex.Value) + 1; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
- h = CellHeight - 1;
- if (y < ColumnHeight)
- {
- return;
- }
- }
-
- if (x > DrawWidth || y > DrawHeight)
- {
- return;
- } // Don't draw if off screen.
-
- _gdi.SetBrush(color);
- _gdi.FillRectangle(x, y, w, h);
- }
-
///
/// Calls QueryItemBkColor callback for all visible cells and fills in the background of those cells.
///
@@ -546,7 +159,7 @@ namespace BizHawk.Client.EmuHawk
for (int i = 0, f = 0; f < range; i++, f++)
{
f += _lagFrames[i];
-
+
Color rowColor = Color.White;
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
@@ -573,7 +186,7 @@ namespace BizHawk.Client.EmuHawk
Column = visibleColumns[j],
RowIndex = i
};
- DrawCellBG(itemColor, cell, visibleColumns);
+ DrawCellBG(e, itemColor, cell, visibleColumns);
}
}
}
@@ -583,7 +196,7 @@ namespace BizHawk.Client.EmuHawk
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
{
f += _lagFrames[i];
-
+
Color rowColor = Color.White;
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
@@ -610,11 +223,13 @@ namespace BizHawk.Client.EmuHawk
Column = visibleColumns[j],
RowIndex = i
};
- DrawCellBG(itemColor, cell, visibleColumns);
+ DrawCellBG(e, itemColor, cell, visibleColumns);
}
}
}
}
}
+
+ #endregion
}
}
diff --git a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.cs b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.cs
index 5bab6dc2e7..98455379bd 100644
--- a/BizHawk.Client.EmuHawk/CustomControls/InputRoll.cs
+++ b/BizHawk.Client.EmuHawk/CustomControls/InputRoll.cs
@@ -15,7 +15,10 @@ namespace BizHawk.Client.EmuHawk
// Row width is specified for horizontal orientation
public partial class InputRoll : Control
{
- private readonly GDIRenderer _gdi;
+ private RollRenderer Renderer = RollRenderer.GDIPlus;
+
+ private Font _commonFont;
+
private readonly SortedSet _selectedItems = new SortedSet(new SortCell());
private readonly VScrollBar _vBar;
@@ -24,8 +27,6 @@ namespace BizHawk.Client.EmuHawk
private readonly Timer _hoverTimer = new Timer();
private readonly byte[] _lagFrames = new byte[256]; // Large enough value that it shouldn't ever need resizing. // apparently not large enough for 4K
- private readonly IntPtr _rotatedFont;
- private readonly IntPtr _normalFont;
private readonly Color _foreColor;
private readonly Color _backColor;
@@ -35,7 +36,6 @@ namespace BizHawk.Client.EmuHawk
private int _maxCharactersInHorizontal = 1;
private int _rowCount;
- private Size _charSize;
private RollColumn _columnDown;
@@ -52,6 +52,9 @@ namespace BizHawk.Client.EmuHawk
public InputRoll()
{
+ // set renderer once at InputRoll instantiation
+ Renderer = (RollRenderer)TAStudio.InputRollRenderer;
+
UseCustomBackground = true;
GridLines = true;
CellWidthPadding = 3;
@@ -59,24 +62,29 @@ namespace BizHawk.Client.EmuHawk
CurrentCell = null;
ScrollMethod = "near";
- var commonFont = new Font("Arial", 8, FontStyle.Bold);
- _normalFont = GDIRenderer.CreateNormalHFont(commonFont, 6);
-
- // PrepDrawString doesn't actually set the font, so this is rather useless.
- // I'm leaving this stuff as-is so it will be a bit easier to fix up with another rendering method.
- _rotatedFont = GDIRenderer.CreateRotatedHFont(commonFont, true);
-
- SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- SetStyle(ControlStyles.UserPaint, true);
- SetStyle(ControlStyles.SupportsTransparentBackColor, true);
- SetStyle(ControlStyles.Opaque, true);
-
- _gdi = new GDIRenderer();
-
- using (var g = CreateGraphics())
- using (_gdi.LockGraphics(g))
+ switch (Renderer)
{
- _charSize = _gdi.MeasureString("A", commonFont); // TODO make this a property so changing it updates other values.
+ case RollRenderer.GDI:
+ _commonFont = new Font("Arial", 8, FontStyle.Bold);
+ _normalFont = GDIRenderer.CreateNormalHFont(_commonFont, 6);
+
+ // PrepDrawString doesn't actually set the font, so this is rather useless.
+ // I'm leaving this stuff as-is so it will be a bit easier to fix up with another rendering method.
+ _rotatedFont = GDIRenderer.CreateRotatedHFont(_commonFont, true);
+
+ SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ SetStyle(ControlStyles.UserPaint, true);
+ SetStyle(ControlStyles.SupportsTransparentBackColor, true);
+ SetStyle(ControlStyles.Opaque, true);
+
+ _gdi = new GDIRenderer();
+ GDIConstruction();
+ break;
+ case RollRenderer.GDIPlus:
+// _commonFont = new Font("Courier New", 8, FontStyle.Bold);
+ _commonFont = new Font("Arial", 8, FontStyle.Bold);
+ GDIPConstruction();
+ break;
}
UpdateCellSize();
@@ -126,11 +134,7 @@ namespace BizHawk.Client.EmuHawk
protected override void Dispose(bool disposing)
{
- _gdi.Dispose();
-
- GDIRenderer.DestroyHFont(_normalFont);
- GDIRenderer.DestroyHFont(_rotatedFont);
-
+ if (Renderer == RollRenderer.GDI) GDIDispose();
base.Dispose(disposing);
}
@@ -193,7 +197,7 @@ namespace BizHawk.Client.EmuHawk
{
return _hBar.SmallChange / CellWidth;
}
-
+ if (CellHeight == 0) CellHeight++;
return _vBar.SmallChange / CellHeight;
}
@@ -643,7 +647,7 @@ namespace BizHawk.Client.EmuHawk
{
return _hBar.Value / CellWidth;
}
-
+ if (CellHeight == 0) CellHeight++;
return _vBar.Value / CellHeight;
}
@@ -771,6 +775,7 @@ namespace BizHawk.Client.EmuHawk
{
get
{
+ if (CellHeight == 0) CellHeight++;
if (HorizontalOrientation)
{
return (DrawWidth - ColumnWidth) / CellWidth;
@@ -789,6 +794,7 @@ namespace BizHawk.Client.EmuHawk
{
get
{
+ if (CellHeight == 0) CellHeight++;
if (HorizontalOrientation)
{
return _vBar.Value / CellHeight;
@@ -805,6 +811,7 @@ namespace BizHawk.Client.EmuHawk
{
get
{
+ if (CellHeight == 0) CellHeight++;
List columnList = VisibleColumns.ToList();
int ret;
if (HorizontalOrientation)
@@ -1009,7 +1016,7 @@ namespace BizHawk.Client.EmuHawk
Refresh();
}
}
- else if (_columnDown != null) // Kind of silly feeling to have this check twice, but the only alternative I can think of has it refreshing twice when pointed column changes with column down, and speed matters
+ else if (_columnDown != null) // Kind of silly feeling to have this check twice, but the only alternative I can think of has it refreshing twice when pointed column changes with column down, and speed matters
{
Refresh();
}
@@ -1579,10 +1586,13 @@ namespace BizHawk.Client.EmuHawk
// See MSDN Page for more information on the dumb ScrollBar.Maximum Property
private void RecalculateScrollBars()
{
+ if (_vBar == null || _hBar == null) return;
+
UpdateDrawSize();
var columns = _columns.VisibleColumns.ToList();
+ if (CellHeight == 0) CellHeight++;
if (HorizontalOrientation)
{
NeedsVScrollbar = columns.Count > DrawHeight / CellHeight;
@@ -1763,6 +1773,8 @@ namespace BizHawk.Client.EmuHawk
{
newCell.RowIndex = PixelsToRows(x);
+ if (CellHeight == 0) CellHeight++;
+
int colIndex = (y + _vBar.Value) / CellHeight;
if (colIndex >= 0 && colIndex < columns.Count)
{
@@ -1798,7 +1810,15 @@ namespace BizHawk.Client.EmuHawk
/// The new width of the RollColumn object.
private int UpdateWidth(RollColumn col)
{
- col.Width = (col.Text.Length * _charSize.Width) + (CellWidthPadding * 4);
+ switch (Renderer)
+ {
+ case RollRenderer.GDI:
+ col.Width = (col.Text.Length * _charSize.Width) + (CellWidthPadding * 4);
+ break;
+ case RollRenderer.GDIPlus:
+ col.Width = (int)Math.Round((col.Text.Length * _charSizeF.Width) + (CellWidthPadding * 4));
+ break;
+ }
return col.Width.Value;
}
@@ -1863,6 +1883,7 @@ namespace BizHawk.Client.EmuHawk
{
return (int)Math.Floor((float)(pixels - ColumnWidth) / CellWidth);
}
+ if (CellHeight == 0) CellHeight++;
return (int)Math.Floor((float)(pixels - ColumnHeight) / CellHeight);
}
@@ -1889,8 +1910,17 @@ namespace BizHawk.Client.EmuHawk
///
private void UpdateCellSize()
{
- CellHeight = _charSize.Height + (CellHeightPadding * 2);
- CellWidth = (_charSize.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4); // Double the padding for horizontal because it looks better
+ switch (Renderer)
+ {
+ case RollRenderer.GDI:
+ CellHeight = _charSize.Height + (CellHeightPadding * 2);
+ CellWidth = (_charSize.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4); // Double the padding for horizontal because it looks better
+ break;
+ case RollRenderer.GDIPlus:
+ CellHeight = (int)Math.Round(_charSizeF.Height + (CellHeightPadding * 2) + 1); // needed for GDI+ to match GDI cell height
+ CellWidth = (int)Math.Round((_charSizeF.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4)); // Double the padding for horizontal because it looks better
+ break;
+ }
}
// SuuperW: Count lag frames between FirstDisplayed and given display position
@@ -2260,6 +2290,12 @@ namespace BizHawk.Client.EmuHawk
}
}
+ public enum RollRenderer
+ {
+ GDI = 0,
+ GDIPlus = 1
+ }
+
#endregion
}
}
diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs
index 08426ffc74..c104438c8e 100644
--- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs
+++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs
@@ -125,6 +125,9 @@ namespace BizHawk.Client.EmuHawk
this.DefaultStateSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SettingsSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.RotateMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.RendererOptionsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.SetRenderer0 = new System.Windows.Forms.ToolStripMenuItem();
+ this.SetRenderer1 = new System.Windows.Forms.ToolStripMenuItem();
this.HideLagFramesSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.HideLagFrames0 = new System.Windows.Forms.ToolStripMenuItem();
this.HideLagFrames1 = new System.Windows.Forms.ToolStripMenuItem();
@@ -964,6 +967,7 @@ namespace BizHawk.Client.EmuHawk
//
this.SettingsSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.RotateMenuItem,
+ this.RendererOptionsMenuItem,
this.HideLagFramesSubMenu,
this.iconsToolStripMenuItem,
this.toolStripSeparator23,
@@ -982,6 +986,34 @@ namespace BizHawk.Client.EmuHawk
this.RotateMenuItem.Text = "Rotate";
this.RotateMenuItem.Click += new System.EventHandler(this.RotateMenuItem_Click);
//
+ // RendererOptionsMenuItem
+ //
+ this.RendererOptionsMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.SetRenderer0,
+ this.SetRenderer1});
+ this.RendererOptionsMenuItem.Name = "RendererOptionsMenuItem";
+ this.RendererOptionsMenuItem.Size = new System.Drawing.Size(183, 22);
+ this.RendererOptionsMenuItem.Text = "Renderer";
+ this.RendererOptionsMenuItem.DropDownOpened += new System.EventHandler(this.SelectedRendererSubMenu_DropDownOpened);
+ //
+ // SetRenderer0
+ //
+ this.SetRenderer0.CheckOnClick = true;
+ this.SetRenderer0.Name = "SetRenderer0";
+ this.SetRenderer0.Size = new System.Drawing.Size(180, 22);
+ this.SetRenderer0.Tag = 0;
+ this.SetRenderer0.Text = "GDI";
+ this.SetRenderer0.Click += new System.EventHandler(this.SetRenderer_Click);
+ //
+ // SetRenderer1
+ //
+ this.SetRenderer1.CheckOnClick = true;
+ this.SetRenderer1.Name = "SetRenderer1";
+ this.SetRenderer1.Size = new System.Drawing.Size(180, 22);
+ this.SetRenderer1.Tag = 1;
+ this.SetRenderer1.Text = "GDI+ (Experimental)";
+ this.SetRenderer1.Click += new System.EventHandler(this.SetRenderer_Click);
+ //
// HideLagFramesSubMenu
//
this.HideLagFramesSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -1816,5 +1848,8 @@ namespace BizHawk.Client.EmuHawk
private System.Windows.Forms.ToolStripMenuItem AutoRestoreOnMouseUpOnlyMenuItem;
private System.Windows.Forms.ToolStripMenuItem SingleClickFloatEditMenuItem;
private System.Windows.Forms.ToolStripMenuItem LoadBranchOnDoubleclickMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem RendererOptionsMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem SetRenderer0;
+ private System.Windows.Forms.ToolStripMenuItem SetRenderer1;
}
-}
\ No newline at end of file
+}
diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs
index f24ce05243..4b62b355ca 100644
--- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs
+++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs
@@ -9,6 +9,7 @@ using BizHawk.Client.Common;
using BizHawk.Client.Common.MovieConversionExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Client.EmuHawk.WinFormExtensions;
+using BizHawk.Common;
namespace BizHawk.Client.EmuHawk
{
@@ -1115,6 +1116,51 @@ namespace BizHawk.Client.EmuHawk
RotateMenuItem.ShortcutKeyDisplayString = TasView.RotateHotkeyStr;
}
+ private void SelectedRendererSubMenu_DropDownOpened(object sender, EventArgs e)
+ {
+ if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows)
+ {
+ if (Global.Config.TasStudioRenderer != InputRollRenderer)
+ {
+ switch (Global.Config.TasStudioRenderer)
+ {
+ case 0:
+ SetRenderer0.Text = "GDI (Pending TAStudio Restart)";
+ SetRenderer0.Enabled = false;
+ SetRenderer0.Checked = true;
+ SetRenderer1.Text = "GDI+ (Experimental)";
+ SetRenderer1.Checked = false;
+ break;
+ case 1:
+ SetRenderer1.Text = "GDI+ (Pending TAStudio Restart)";
+ SetRenderer1.Enabled = false;
+ SetRenderer1.Checked = true;
+ SetRenderer0.Text = "GDI";
+ SetRenderer0.Checked = false;
+ break;
+ }
+ }
+ else
+ {
+ SetRenderer0.Text = "GDI";
+ SetRenderer0.Enabled = true;
+ SetRenderer1.Text = "GDI+ (Experimental)";
+ SetRenderer1.Enabled = true;
+ SetRenderer0.Checked = Global.Config.TasStudioRenderer == 0;
+ SetRenderer1.Checked = Global.Config.TasStudioRenderer == 1;
+ }
+ }
+ else
+ {
+ SetRenderer0.Checked = false;
+ SetRenderer0.Enabled = false;
+ SetRenderer0.Visible = false;
+ SetRenderer1.Checked = true;
+ SetRenderer1.Enabled = false;
+ SetRenderer1.Visible = true;
+ }
+ }
+
private void HideLagFramesSubMenu_DropDownOpened(object sender, EventArgs e)
{
HideLagFrames0.Checked = TasView.LagFramesToHide == 0;
@@ -1163,6 +1209,16 @@ namespace BizHawk.Client.EmuHawk
CurrentTasMovie.FlagChanges();
}
+ private void SetRenderer_Click(object sender, EventArgs e)
+ {
+ var incoming = (int)(sender as ToolStripMenuItem).Tag;
+ if (incoming != InputRollRenderer)
+ {
+ MessageBox.Show("Changing the input roll renderer requires a\nmanual restart of TAStudio", "Renderer Change Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ Global.Config.TasStudioRenderer = incoming;
+ }
+
private void HideLagFramesX_Click(object sender, EventArgs e)
{
TasView.LagFramesToHide = (int)((ToolStripMenuItem)sender).Tag;
diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
index 85a08c5ebe..67035181b3 100644
--- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
+++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
@@ -15,6 +15,7 @@ using BizHawk.Client.Common.MovieConversionExtensions;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions;
+using BizHawk.Common;
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
namespace BizHawk.Client.EmuHawk
@@ -25,6 +26,13 @@ namespace BizHawk.Client.EmuHawk
public TasMovie CurrentTasMovie => Global.MovieSession.Movie as TasMovie;
private MainForm Mainform => GlobalWin.MainForm;
+ ///
+ /// Static settings so that InputRoll.cs can determine its renderer ahead of instantiation
+ /// 0: GDI
+ /// 1: GDI+
+ ///
+ public static int InputRollRenderer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? 0 : 1;
+
public bool IsInMenuLoop { get; private set; }
public string StatesPath => PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null);
@@ -113,6 +121,10 @@ namespace BizHawk.Client.EmuHawk
public TAStudio()
{
Settings = new TAStudioSettings();
+
+ // input roll renderer must be set before InputRoll initialisation
+ InputRollRenderer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? Global.Config.TasStudioRenderer : 1;
+
InitializeComponent();
InitializeSeekWorker();
diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx
index 30922f753b..34d44a8aa8 100644
--- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx
+++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.resx
@@ -123,19 +123,19 @@
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALAQAA
- CwEBNnBPWwAAAk1JREFUOE+VkktvUlEUhVsfsdHoREcOHJr4C/RPONHoXzBxoOlAJybOlAZtkdSa2piY
- NsjjFiiX8qY8ChYL+ECB2lKB8rq0k5bEmiiRbtc+6b2B6MTBR/ZZa+919j3tEBH9RbudHD6E63/2qAwc
- treT58BVRVnWl8vBbLEg7wNC/QPaMrwb4GT/jFa024mzQLe56c9GwjM7klXXlcw6ksyPSbLoKByc/lUq
- +TbQMwrODARAGAF3SxtexSMbf8vOCVp9ZyK+/euaW9TO+SfksOlprSjvoteAjU5rAYqSuFyvR1PR8Ewv
- GJii8rcAoYFSb+d4gDAgNI/8jGTHOFUroT3410QAHuk4Am4Vi/KOzz2JGxfFcLMZI3wK5T7ZqaXEhcYb
- WU2PKJM2H7Ra8XE14AQO91dTpk4k9JLq9YgYHghoxcWZPa/bSCH/C2o0orPaBo1GbDQee9VJxF+zoYFP
- wtpGWgpN0/uMRWgcyiG1WsSkBhxFwG0E7AV8z2lrKyxuYvgBs2kLr4z1XcLj4SA2gD+nBhxB8p1sxtKZ
- t4xR/otTDNdqS1oQw7ezx2/AfxVok1oAmh+WSt7v/MKLLgOtr3tEQD+sseeyPyX0dqHdVAOGq9XQPazX
- /JyzH9itY+SQ9LSSnKV8fkHANWvsoYc/JYaZERHAPzicBw9AoZBf+BnwTZEN/4G2N4egZg1eDz05cIHn
- tACmUgmeAtdhRsvlwH6x6Dr4+EESoO5B68JLo+eSOjMQwKDpGLgCJtDoBysgBXzQDOBifz8zcPh/aOgP
- 7nYTiVA2JaoAAAAASUVORK5CYII=
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
+ JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsBAAALAQE2cE9bAAACTUlE
+ QVQ4T5WSS29SURSFWx+x0ehERw4cmvgL9E840ehfMHGg6UAnJs6UBm2R1JramJg2yOMWKJfypjwKFgv4
+ QIHaUoHyurSTlsSaKJFu1z7pvYHoxMFH9llr73X2Pe0QEf1Fu50cPoTrf/aoDBy2t5PnwFVFWdaXy8Fs
+ sSDvA0L9A9oyvBvgZP+MVrTbibNAt7npz0bCMzuSVdeVzDqSzI9JsugoHJz+VSr5NtAzCs4MBEAYAXdL
+ G17FIxt/y84JWn1nIr7965pb1M75J+Sw6WmtKO+i14CNTmsBipK4XK9HU9HwTC8YmKLytwChgVJv53iA
+ MCA0j/yMZMc4VSuhPfjXRAAe6TgCbhWL8o7PPYkbF8VwsxkjfArlPtmppcSFxhtZTY8okzYftFrxcTXg
+ BA73V1OmTiT0kur1iBgeCGjFxZk9r9tIIf8LajSis9oGjUZsNB571UnEX7OhgU/C2kZaCk3T+4xFaBzK
+ IbVaxKQGHEXAbQTsBXzPaWsrLG5i+AGzaQuvjPVdwuPhIDaAP6cGHEHynWzG0pm3jFH+i1MM12pLWhDD
+ t7PHb8B/FWiTWgCaH5ZK3u/8wosuA62ve0RAP6yx57I/JfR2od1UA4ar1dA9rNf8nLMf2K1j5JD0tJKc
+ pXx+QcA1a+yhhz8lhpkREcA/OJwHD0ChkF/4GfBNkQ3/gbY3h6BmDV4PPTlwgee0AKZSCZ4C12FGy+XA
+ frHoOvj4QRKg7kHrwkuj55I6MxDAoOkYuAIm0OgHKyAFfNAM4GJ/PzNw+H9o6A/udhOJUDYlqgAAAABJ
+ RU5ErkJggg==
| |