gb gpu view: fix bug due to scroll bar hilarity. gba gpu view: implement scanline callbacks
This commit is contained in:
parent
f23e777032
commit
6412d6d93e
BizHawk.Emulation/Consoles/Nintendo/GBA
BizHawk.MultiClient
libmeteor
|
@ -250,5 +250,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
/// <param name="val"></param>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void libmeteor_writebus(uint addr, byte val);
|
||||
|
||||
/// <summary>
|
||||
/// type of the scanline callback
|
||||
/// </summary>
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void ScanlineCallback();
|
||||
|
||||
/// <summary>
|
||||
/// set a callback to coincide with vcount interrupts
|
||||
/// </summary>
|
||||
/// <param name="callback">null to clear</param>
|
||||
/// <param name="scanline">0-227, 160 occurring first in a frame</param>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void libmeteor_setscanlinecallback(ScanlineCallback callback, int scanline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
{
|
||||
if (bios.Length != 16384)
|
||||
throw new Exception("GBA bios must be exactly 16384 bytes!");
|
||||
if (rom.Length > 32 * 1024 * 1024)
|
||||
throw new Exception("Rom is too big!");
|
||||
Init();
|
||||
LibMeteor.libmeteor_hardreset();
|
||||
LibMeteor.libmeteor_loadbios(bios, (uint)bios.Length);
|
||||
|
@ -46,6 +48,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
LibMeteor.libmeteor_frameadvance();
|
||||
if (IsLagFrame)
|
||||
LagCount++;
|
||||
if (EndOfFrameCallback != null)
|
||||
EndOfFrameCallback();
|
||||
}
|
||||
|
||||
public int Frame { get; private set; }
|
||||
|
@ -376,6 +380,40 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
CoreInputComm.Tracer.Put(msg);
|
||||
}
|
||||
|
||||
Action EndOfFrameCallback = null;
|
||||
LibMeteor.ScanlineCallback scanlinecb = null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="callback">null to cancel</param>
|
||||
/// <param name="scanline">0-227, null = end of frame</param>
|
||||
public void SetScanlineCallback(Action callback, int? scanline)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
LibMeteor.libmeteor_setscanlinecallback(null, 400);
|
||||
EndOfFrameCallback = null;
|
||||
scanlinecb = null;
|
||||
}
|
||||
else if (scanline == null)
|
||||
{
|
||||
LibMeteor.libmeteor_setscanlinecallback(null, 400);
|
||||
EndOfFrameCallback = callback;
|
||||
scanlinecb = null;
|
||||
}
|
||||
else if (scanline >= 0 && scanline <= 227)
|
||||
{
|
||||
scanlinecb = new LibMeteor.ScanlineCallback(callback);
|
||||
LibMeteor.libmeteor_setscanlinecallback(scanlinecb, (int)scanline);
|
||||
EndOfFrameCallback = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Scanline must be in [0, 227]!");
|
||||
}
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (attachedcore != null)
|
||||
|
|
|
@ -32,6 +32,13 @@
|
|||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.buttonShowWidget = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.radioButtonFrame = new System.Windows.Forms.RadioButton();
|
||||
this.radioButtonScanline = new System.Windows.Forms.RadioButton();
|
||||
this.radioButtonManual = new System.Windows.Forms.RadioButton();
|
||||
this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
|
||||
this.buttonRefresh = new System.Windows.Forms.Button();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// listBoxWidgets
|
||||
|
@ -72,11 +79,80 @@
|
|||
this.buttonShowWidget.UseVisualStyleBackColor = true;
|
||||
this.buttonShowWidget.Click += new System.EventHandler(this.buttonShowWidget_Click);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.buttonRefresh);
|
||||
this.groupBox1.Controls.Add(this.hScrollBar1);
|
||||
this.groupBox1.Controls.Add(this.radioButtonManual);
|
||||
this.groupBox1.Controls.Add(this.radioButtonScanline);
|
||||
this.groupBox1.Controls.Add(this.radioButtonFrame);
|
||||
this.groupBox1.Location = new System.Drawing.Point(15, 220);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(117, 173);
|
||||
this.groupBox1.TabIndex = 4;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Refresh";
|
||||
//
|
||||
// radioButtonFrame
|
||||
//
|
||||
this.radioButtonFrame.AutoSize = true;
|
||||
this.radioButtonFrame.Location = new System.Drawing.Point(6, 19);
|
||||
this.radioButtonFrame.Name = "radioButtonFrame";
|
||||
this.radioButtonFrame.Size = new System.Drawing.Size(54, 17);
|
||||
this.radioButtonFrame.TabIndex = 0;
|
||||
this.radioButtonFrame.Text = "Frame";
|
||||
this.radioButtonFrame.UseVisualStyleBackColor = true;
|
||||
this.radioButtonFrame.CheckedChanged += new System.EventHandler(this.radioButtonFrame_CheckedChanged);
|
||||
//
|
||||
// radioButtonScanline
|
||||
//
|
||||
this.radioButtonScanline.AutoSize = true;
|
||||
this.radioButtonScanline.Location = new System.Drawing.Point(6, 42);
|
||||
this.radioButtonScanline.Name = "radioButtonScanline";
|
||||
this.radioButtonScanline.Size = new System.Drawing.Size(66, 17);
|
||||
this.radioButtonScanline.TabIndex = 1;
|
||||
this.radioButtonScanline.Text = "Scanline";
|
||||
this.radioButtonScanline.UseVisualStyleBackColor = true;
|
||||
this.radioButtonScanline.CheckedChanged += new System.EventHandler(this.radioButtonScanline_CheckedChanged);
|
||||
//
|
||||
// radioButtonManual
|
||||
//
|
||||
this.radioButtonManual.AutoSize = true;
|
||||
this.radioButtonManual.Location = new System.Drawing.Point(6, 81);
|
||||
this.radioButtonManual.Name = "radioButtonManual";
|
||||
this.radioButtonManual.Size = new System.Drawing.Size(60, 17);
|
||||
this.radioButtonManual.TabIndex = 2;
|
||||
this.radioButtonManual.TabStop = true;
|
||||
this.radioButtonManual.Text = "Manual";
|
||||
this.radioButtonManual.UseVisualStyleBackColor = true;
|
||||
this.radioButtonManual.CheckedChanged += new System.EventHandler(this.radioButtonManual_CheckedChanged);
|
||||
//
|
||||
// hScrollBar1
|
||||
//
|
||||
this.hScrollBar1.LargeChange = 20;
|
||||
this.hScrollBar1.Location = new System.Drawing.Point(3, 62);
|
||||
this.hScrollBar1.Maximum = 246;
|
||||
this.hScrollBar1.Name = "hScrollBar1";
|
||||
this.hScrollBar1.Size = new System.Drawing.Size(111, 16);
|
||||
this.hScrollBar1.TabIndex = 3;
|
||||
this.hScrollBar1.ValueChanged += new System.EventHandler(this.hScrollBar1_ValueChanged);
|
||||
//
|
||||
// buttonRefresh
|
||||
//
|
||||
this.buttonRefresh.Location = new System.Drawing.Point(6, 104);
|
||||
this.buttonRefresh.Name = "buttonRefresh";
|
||||
this.buttonRefresh.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonRefresh.TabIndex = 4;
|
||||
this.buttonRefresh.Text = "Refresh";
|
||||
this.buttonRefresh.UseVisualStyleBackColor = true;
|
||||
this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click);
|
||||
//
|
||||
// GBAGPUView
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(636, 405);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.buttonShowWidget);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.panel1);
|
||||
|
@ -84,7 +160,10 @@
|
|||
this.Name = "GBAGPUView";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
|
||||
this.Text = "GBA GPU Viewer";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GBAGPUView_FormClosed);
|
||||
this.Load += new System.EventHandler(this.GBAGPUView_Load);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -96,6 +175,12 @@
|
|||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button buttonShowWidget;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Button buttonRefresh;
|
||||
private System.Windows.Forms.HScrollBar hScrollBar1;
|
||||
private System.Windows.Forms.RadioButton radioButtonManual;
|
||||
private System.Windows.Forms.RadioButton radioButtonScanline;
|
||||
private System.Windows.Forms.RadioButton radioButtonFrame;
|
||||
|
||||
}
|
||||
}
|
|
@ -35,6 +35,9 @@ namespace BizHawk.MultiClient.GBAtools
|
|||
Buffer.BlockCopy(tmp, 0, ColorConversion, sizeof(int) * tmp.Length, sizeof(int) * tmp.Length);
|
||||
|
||||
GenerateWidgets();
|
||||
radioButtonFrame.Checked = true;
|
||||
hScrollBar1_ValueChanged(null, null);
|
||||
RecomputeRefresh();
|
||||
}
|
||||
|
||||
#region drawing primitives
|
||||
|
@ -659,7 +662,22 @@ namespace BizHawk.MultiClient.GBAtools
|
|||
return;
|
||||
if (gba != null)
|
||||
{
|
||||
DrawEverything();
|
||||
if (cbscanline_emu != cbscanline)
|
||||
{
|
||||
cbscanline_emu = cbscanline;
|
||||
if (cbscanline == -2) // manual, do nothing
|
||||
{
|
||||
gba.SetScanlineCallback(null, null);
|
||||
}
|
||||
else if (cbscanline == -1) // end of frame
|
||||
{
|
||||
gba.SetScanlineCallback(DrawEverything, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
gba.SetScanlineCallback(DrawEverything, cbscanline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,5 +706,65 @@ namespace BizHawk.MultiClient.GBAtools
|
|||
{
|
||||
ShowSelectedWidget();
|
||||
}
|
||||
|
||||
int cbscanline;
|
||||
int cbscanline_emu = 500;
|
||||
|
||||
void RecomputeRefresh()
|
||||
{
|
||||
if (radioButtonFrame.Checked)
|
||||
{
|
||||
hScrollBar1.Enabled = false;
|
||||
buttonRefresh.Enabled = false;
|
||||
cbscanline = -1;
|
||||
}
|
||||
else if (radioButtonScanline.Checked)
|
||||
{
|
||||
hScrollBar1.Enabled = true;
|
||||
buttonRefresh.Enabled = false;
|
||||
cbscanline = (hScrollBar1.Value + 160) % 228;
|
||||
}
|
||||
else if (radioButtonManual.Checked)
|
||||
{
|
||||
hScrollBar1.Enabled = false;
|
||||
buttonRefresh.Enabled = true;
|
||||
cbscanline = -2;
|
||||
}
|
||||
}
|
||||
|
||||
private void radioButtonFrame_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
RecomputeRefresh();
|
||||
}
|
||||
|
||||
private void radioButtonScanline_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
RecomputeRefresh();
|
||||
}
|
||||
|
||||
private void hScrollBar1_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
cbscanline = (hScrollBar1.Value + 160) % 228;
|
||||
radioButtonScanline.Text = "Scanline " + cbscanline;
|
||||
}
|
||||
|
||||
private void radioButtonManual_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
RecomputeRefresh();
|
||||
}
|
||||
|
||||
private void buttonRefresh_Click(object sender, EventArgs e)
|
||||
{
|
||||
DrawEverything();
|
||||
}
|
||||
|
||||
private void GBAGPUView_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
if (gba != null)
|
||||
{
|
||||
gba.SetScanlineCallback(null, null);
|
||||
gba = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
// hScrollBarScanline
|
||||
//
|
||||
this.hScrollBarScanline.Location = new System.Drawing.Point(76, 45);
|
||||
this.hScrollBarScanline.Maximum = 153;
|
||||
this.hScrollBarScanline.Maximum = 162;
|
||||
this.hScrollBarScanline.Name = "hScrollBarScanline";
|
||||
this.hScrollBarScanline.Size = new System.Drawing.Size(192, 16);
|
||||
this.hScrollBarScanline.TabIndex = 21;
|
||||
|
|
Binary file not shown.
|
@ -217,3 +217,21 @@ EXPORT void libmeteor_writebus(uint32_t addr, uint8_t val)
|
|||
{
|
||||
AMeteor::_memory.Write8(addr, val);
|
||||
}
|
||||
|
||||
int slcallbackline = 400;
|
||||
void (*slcallback)() = NULL;
|
||||
|
||||
EXPORT void libmeteor_setscanlinecallback(void (*callback)(), int scanline)
|
||||
{
|
||||
if (!callback)
|
||||
slcallbackline = 400;
|
||||
else
|
||||
slcallbackline = scanline;
|
||||
slcallback = callback;
|
||||
}
|
||||
|
||||
void scanlinecallback_bizhawk()
|
||||
{
|
||||
if (slcallback)
|
||||
slcallback();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ void abort_bizhawk(const char *msg);
|
|||
void keyupdate_bizhawk();
|
||||
extern bool traceenabled;
|
||||
void trace_bizhawk(std::string msg);
|
||||
extern int slcallbackline;
|
||||
void scanlinecallback_bizhawk();
|
||||
|
||||
#if 0
|
||||
#define met_abort(str) \
|
||||
|
|
|
@ -94,7 +94,8 @@ namespace AMeteor
|
|||
else // no vcount match
|
||||
dispstat &= ~(uint16_t)0x4;
|
||||
// scanline callback for frontend
|
||||
// ...
|
||||
if (slcallbackline == vcount)
|
||||
scanlinecallback_bizhawk();
|
||||
}
|
||||
else // if we were not H-Blanking
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue