vbanext: support GPU VIEW. it should still work in meteor...
This commit is contained in:
parent
23ae71382e
commit
9c24c180f2
|
@ -39,7 +39,6 @@
|
||||||
this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
|
this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
|
||||||
this.radioButtonManual = new System.Windows.Forms.RadioButton();
|
this.radioButtonManual = new System.Windows.Forms.RadioButton();
|
||||||
this.radioButtonScanline = new System.Windows.Forms.RadioButton();
|
this.radioButtonScanline = new System.Windows.Forms.RadioButton();
|
||||||
this.radioButtonFrame = new System.Windows.Forms.RadioButton();
|
|
||||||
this.labelClipboard = new System.Windows.Forms.Label();
|
this.labelClipboard = new System.Windows.Forms.Label();
|
||||||
this.timerMessage = new System.Windows.Forms.Timer(this.components);
|
this.timerMessage = new System.Windows.Forms.Timer(this.components);
|
||||||
this.groupBox1.SuspendLayout();
|
this.groupBox1.SuspendLayout();
|
||||||
|
@ -90,7 +89,6 @@
|
||||||
this.groupBox1.Controls.Add(this.hScrollBar1);
|
this.groupBox1.Controls.Add(this.hScrollBar1);
|
||||||
this.groupBox1.Controls.Add(this.radioButtonManual);
|
this.groupBox1.Controls.Add(this.radioButtonManual);
|
||||||
this.groupBox1.Controls.Add(this.radioButtonScanline);
|
this.groupBox1.Controls.Add(this.radioButtonScanline);
|
||||||
this.groupBox1.Controls.Add(this.radioButtonFrame);
|
|
||||||
this.groupBox1.Location = new System.Drawing.Point(15, 220);
|
this.groupBox1.Location = new System.Drawing.Point(15, 220);
|
||||||
this.groupBox1.Name = "groupBox1";
|
this.groupBox1.Name = "groupBox1";
|
||||||
this.groupBox1.Size = new System.Drawing.Size(134, 133);
|
this.groupBox1.Size = new System.Drawing.Size(134, 133);
|
||||||
|
@ -141,17 +139,6 @@
|
||||||
this.radioButtonScanline.UseVisualStyleBackColor = true;
|
this.radioButtonScanline.UseVisualStyleBackColor = true;
|
||||||
this.radioButtonScanline.CheckedChanged += new System.EventHandler(this.radioButtonScanline_CheckedChanged);
|
this.radioButtonScanline.CheckedChanged += new System.EventHandler(this.radioButtonScanline_CheckedChanged);
|
||||||
//
|
//
|
||||||
// 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);
|
|
||||||
//
|
|
||||||
// labelClipboard
|
// labelClipboard
|
||||||
//
|
//
|
||||||
this.labelClipboard.AutoSize = true;
|
this.labelClipboard.AutoSize = true;
|
||||||
|
@ -205,7 +192,6 @@
|
||||||
private System.Windows.Forms.HScrollBar hScrollBar1;
|
private System.Windows.Forms.HScrollBar hScrollBar1;
|
||||||
private System.Windows.Forms.RadioButton radioButtonManual;
|
private System.Windows.Forms.RadioButton radioButtonManual;
|
||||||
private System.Windows.Forms.RadioButton radioButtonScanline;
|
private System.Windows.Forms.RadioButton radioButtonScanline;
|
||||||
private System.Windows.Forms.RadioButton radioButtonFrame;
|
|
||||||
private System.Windows.Forms.Label labelClipboard;
|
private System.Windows.Forms.Label labelClipboard;
|
||||||
private System.Windows.Forms.Timer timerMessage;
|
private System.Windows.Forms.Timer timerMessage;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public partial class GBAGPUView : Form, IToolForm
|
public partial class GBAGPUView : Form, IToolForm
|
||||||
{
|
{
|
||||||
GBA gba;
|
IGBAGPUViewable gba;
|
||||||
|
|
||||||
// emulator memory areas
|
// emulator memory areas
|
||||||
private IntPtr vram;
|
private IntPtr vram;
|
||||||
|
@ -37,9 +37,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
ColorConversion = new int[65536];
|
ColorConversion = new int[65536];
|
||||||
Buffer.BlockCopy(tmp, 0, ColorConversion, 0, sizeof(int) * tmp.Length);
|
Buffer.BlockCopy(tmp, 0, ColorConversion, 0, sizeof(int) * tmp.Length);
|
||||||
Buffer.BlockCopy(tmp, 0, ColorConversion, sizeof(int) * tmp.Length, sizeof(int) * tmp.Length);
|
Buffer.BlockCopy(tmp, 0, ColorConversion, sizeof(int) * tmp.Length, sizeof(int) * tmp.Length);
|
||||||
|
radioButtonManual.Checked = true;
|
||||||
GenerateWidgets();
|
GenerateWidgets();
|
||||||
radioButtonFrame.Checked = true;
|
|
||||||
hScrollBar1_ValueChanged(null, null);
|
hScrollBar1_ValueChanged(null, null);
|
||||||
RecomputeRefresh();
|
RecomputeRefresh();
|
||||||
}
|
}
|
||||||
|
@ -680,10 +679,14 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
{
|
{
|
||||||
gba = Global.Emulator as GBA;
|
gba = Global.Emulator as IGBAGPUViewable;
|
||||||
if (gba != null)
|
if (gba != null)
|
||||||
{
|
{
|
||||||
gba.GetGPUMemoryAreas(out vram, out palram, out oam, out mmio);
|
var mem = gba.GetMemoryAreas();
|
||||||
|
vram = mem.vram;
|
||||||
|
palram = mem.palram;
|
||||||
|
oam = mem.oam;
|
||||||
|
mmio = mem.mmio;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -702,17 +705,13 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (_cbscanlineEmu != _cbscanline)
|
if (_cbscanlineEmu != _cbscanline)
|
||||||
{
|
{
|
||||||
_cbscanlineEmu = _cbscanline;
|
_cbscanlineEmu = _cbscanline;
|
||||||
if (_cbscanline == -2) // manual, do nothing
|
if (!_cbscanline.HasValue) // manual, deactivate callback
|
||||||
{
|
{
|
||||||
gba.SetScanlineCallback(null, null);
|
gba.SetScanlineCallback(null, 0);
|
||||||
}
|
|
||||||
else if (_cbscanline == -1) // end of frame
|
|
||||||
{
|
|
||||||
gba.SetScanlineCallback(DrawEverything, null);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gba.SetScanlineCallback(DrawEverything, _cbscanline);
|
gba.SetScanlineCallback(DrawEverything, _cbscanline.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -751,18 +750,12 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
#region refresh control
|
#region refresh control
|
||||||
|
|
||||||
private int _cbscanline;
|
private int? _cbscanline = null;
|
||||||
private int _cbscanlineEmu = 500;
|
private int? _cbscanlineEmu = 500;
|
||||||
|
|
||||||
private void RecomputeRefresh()
|
private void RecomputeRefresh()
|
||||||
{
|
{
|
||||||
if (radioButtonFrame.Checked)
|
if (radioButtonScanline.Checked)
|
||||||
{
|
|
||||||
hScrollBar1.Enabled = false;
|
|
||||||
buttonRefresh.Enabled = false;
|
|
||||||
_cbscanline = -1;
|
|
||||||
}
|
|
||||||
else if (radioButtonScanline.Checked)
|
|
||||||
{
|
{
|
||||||
hScrollBar1.Enabled = true;
|
hScrollBar1.Enabled = true;
|
||||||
buttonRefresh.Enabled = false;
|
buttonRefresh.Enabled = false;
|
||||||
|
@ -772,7 +765,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
hScrollBar1.Enabled = false;
|
hScrollBar1.Enabled = false;
|
||||||
buttonRefresh.Enabled = true;
|
buttonRefresh.Enabled = true;
|
||||||
_cbscanline = -2;
|
_cbscanline = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,7 +801,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
if (gba != null)
|
if (gba != null)
|
||||||
{
|
{
|
||||||
gba.SetScanlineCallback(null, null);
|
gba.SetScanlineCallback(null, 0);
|
||||||
gba = null;
|
gba = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,7 @@
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\GBColors.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\GBColors.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\LibGambatte.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\LibGambatte.cs" />
|
||||||
|
<Compile Include="Consoles\Nintendo\GBA\IGBAGPUViewable.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\GBA\LibMeteor.cs" />
|
<Compile Include="Consoles\Nintendo\GBA\LibMeteor.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\GBA\LibVBANext.cs" />
|
<Compile Include="Consoles\Nintendo\GBA\LibVBANext.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\GBA\Meteor.cs" />
|
<Compile Include="Consoles\Nintendo\GBA\Meteor.cs" />
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
|
{
|
||||||
|
public interface IGBAGPUViewable
|
||||||
|
{
|
||||||
|
GBAGPUMemoryAreas GetMemoryAreas();
|
||||||
|
/// <summary>
|
||||||
|
/// calls correspond to entering hblank (maybe) and in a regular frame, the sequence of calls will be 160, 161, ..., 227, 0, ..., 159
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="callback"></param>
|
||||||
|
/// <param name="scanline"></param>
|
||||||
|
void SetScanlineCallback(Action callback, int scanline);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GBAGPUMemoryAreas
|
||||||
|
{
|
||||||
|
public IntPtr vram;
|
||||||
|
public IntPtr oam;
|
||||||
|
public IntPtr mmio;
|
||||||
|
public IntPtr palram;
|
||||||
|
}
|
||||||
|
}
|
|
@ -130,6 +130,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
[DllImport(dllname, CallingConvention = cc)]
|
[DllImport(dllname, CallingConvention = cc)]
|
||||||
public static extern byte SystemBusRead(IntPtr g, int addr);
|
public static extern byte SystemBusRead(IntPtr g, int addr);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(cc)]
|
||||||
|
public delegate void StandardCallback();
|
||||||
|
|
||||||
|
[DllImport(dllname, CallingConvention = cc)]
|
||||||
|
public static extern void SetScanlineCallback(IntPtr g, StandardCallback cb, int scanline);
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public class MemoryAreas
|
public class MemoryAreas
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
isPorted: true,
|
isPorted: true,
|
||||||
isReleased: false
|
isReleased: false
|
||||||
)]
|
)]
|
||||||
public class GBA : IEmulator, IVideoProvider, ISyncSoundProvider
|
public class GBA : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable
|
||||||
{
|
{
|
||||||
public Dictionary<string, int> GetCpuFlagsAndRegisters()
|
public Dictionary<string, int> GetCpuFlagsAndRegisters()
|
||||||
{
|
{
|
||||||
|
@ -83,8 +83,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
LibMeteor.libmeteor_frameadvance();
|
LibMeteor.libmeteor_frameadvance();
|
||||||
if (IsLagFrame)
|
if (IsLagFrame)
|
||||||
LagCount++;
|
LagCount++;
|
||||||
if (EndOfFrameCallback != null)
|
|
||||||
EndOfFrameCallback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Frame { get; private set; }
|
public int Frame { get; private set; }
|
||||||
|
@ -306,22 +304,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
MemoryDomains = new MemoryDomainList(_MemoryDomains);
|
MemoryDomains = new MemoryDomainList(_MemoryDomains);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetGPUMemoryAreas(out IntPtr vram, out IntPtr palram, out IntPtr oam, out IntPtr mmio)
|
|
||||||
{
|
|
||||||
IntPtr _vram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.vram);
|
|
||||||
IntPtr _palram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.palram);
|
|
||||||
IntPtr _oam = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.oam);
|
|
||||||
IntPtr _mmio = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.io);
|
|
||||||
|
|
||||||
if (_vram == IntPtr.Zero || _palram == IntPtr.Zero || _oam == IntPtr.Zero || _mmio == IntPtr.Zero)
|
|
||||||
throw new Exception("libmeteor_getmemoryarea() failed!");
|
|
||||||
|
|
||||||
vram = _vram;
|
|
||||||
palram = _palram;
|
|
||||||
oam = _oam;
|
|
||||||
mmio = _mmio;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>like libsnes, the library is single-instance</summary>
|
/// <summary>like libsnes, the library is single-instance</summary>
|
||||||
|
@ -438,39 +420,44 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
CoreComm.Tracer.Put(msg);
|
CoreComm.Tracer.Put(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Action EndOfFrameCallback = null;
|
GBAGPUMemoryAreas IGBAGPUViewable.GetMemoryAreas()
|
||||||
LibMeteor.ScanlineCallback scanlinecb = null;
|
{
|
||||||
|
IntPtr _vram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.vram);
|
||||||
|
IntPtr _palram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.palram);
|
||||||
|
IntPtr _oam = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.oam);
|
||||||
|
IntPtr _mmio = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.io);
|
||||||
|
|
||||||
/// <summary>
|
if (_vram == IntPtr.Zero || _palram == IntPtr.Zero || _oam == IntPtr.Zero || _mmio == IntPtr.Zero)
|
||||||
///
|
throw new Exception("libmeteor_getmemoryarea() failed!");
|
||||||
/// </summary>
|
|
||||||
/// <param name="callback">null to cancel</param>
|
return new GBAGPUMemoryAreas
|
||||||
/// <param name="scanline">0-227, null = end of frame</param>
|
|
||||||
public void SetScanlineCallback(Action callback, int? scanline)
|
|
||||||
{
|
{
|
||||||
if (callback == null)
|
vram = _vram,
|
||||||
{
|
palram = _palram,
|
||||||
LibMeteor.libmeteor_setscanlinecallback(null, 400);
|
oam = _oam,
|
||||||
EndOfFrameCallback = null;
|
mmio = _mmio
|
||||||
scanlinecb = null;
|
};
|
||||||
}
|
}
|
||||||
else if (scanline == null)
|
|
||||||
|
void IGBAGPUViewable.SetScanlineCallback(Action callback, int scanline)
|
||||||
{
|
{
|
||||||
LibMeteor.libmeteor_setscanlinecallback(null, 400);
|
if (scanline < 0 || scanline > 227)
|
||||||
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]!");
|
throw new ArgumentOutOfRangeException("Scanline must be in [0, 227]!");
|
||||||
}
|
}
|
||||||
|
if (callback == null)
|
||||||
|
{
|
||||||
|
scanlinecb = null;
|
||||||
|
LibMeteor.libmeteor_setscanlinecallback(null, 0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanlinecb = new LibMeteor.ScanlineCallback(callback);
|
||||||
|
LibMeteor.libmeteor_setscanlinecallback(scanlinecb, scanline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LibMeteor.ScanlineCallback scanlinecb = null;
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ using BizHawk.Common;
|
||||||
namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
{
|
{
|
||||||
[CoreAttributes("VBA-Next", "TODO", true, false, "cd508312a29ed8c29dacac1b11c2dce56c338a54", "https://github.com/libretro/vba-next")]
|
[CoreAttributes("VBA-Next", "TODO", true, false, "cd508312a29ed8c29dacac1b11c2dce56c338a54", "https://github.com/libretro/vba-next")]
|
||||||
public class VBANext : IEmulator, IVideoProvider, ISyncSoundProvider
|
public class VBANext : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable
|
||||||
{
|
{
|
||||||
IntPtr Core;
|
IntPtr Core;
|
||||||
|
|
||||||
|
@ -254,6 +254,39 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||||
|
|
||||||
#region Debugging
|
#region Debugging
|
||||||
|
|
||||||
|
LibVBANext.StandardCallback scanlinecb;
|
||||||
|
|
||||||
|
GBAGPUMemoryAreas IGBAGPUViewable.GetMemoryAreas()
|
||||||
|
{
|
||||||
|
var s = new LibVBANext.MemoryAreas();
|
||||||
|
LibVBANext.GetMemoryAreas(Core, s);
|
||||||
|
return new GBAGPUMemoryAreas
|
||||||
|
{
|
||||||
|
mmio = s.mmio,
|
||||||
|
oam = s.oam,
|
||||||
|
palram = s.palram,
|
||||||
|
vram = s.vram
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void IGBAGPUViewable.SetScanlineCallback(Action callback, int scanline)
|
||||||
|
{
|
||||||
|
if (scanline < 0 || scanline > 227)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("Scanline must be in [0, 227]!");
|
||||||
|
}
|
||||||
|
if (callback == null)
|
||||||
|
{
|
||||||
|
scanlinecb = null;
|
||||||
|
LibVBANext.SetScanlineCallback(Core, scanlinecb, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanlinecb = new LibVBANext.StandardCallback(callback);
|
||||||
|
LibVBANext.SetScanlineCallback(Core, scanlinecb, scanline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InitMemoryDomains()
|
void InitMemoryDomains()
|
||||||
{
|
{
|
||||||
var mm = new List<MemoryDomain>();
|
var mm = new List<MemoryDomain>();
|
||||||
|
|
Binary file not shown.
|
@ -12548,6 +12548,8 @@ updateLoop:
|
||||||
io_registers[REG_IF] |= 2;
|
io_registers[REG_IF] |= 2;
|
||||||
UPDATE_REG(0x202, io_registers[REG_IF]);
|
UPDATE_REG(0x202, io_registers[REG_IF]);
|
||||||
}
|
}
|
||||||
|
if (scanlineCallback && scanlineCallbackLine == io_registers[REG_VCOUNT])
|
||||||
|
scanlineCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(io_registers[REG_VCOUNT] >= 228)
|
if(io_registers[REG_VCOUNT] >= 228)
|
||||||
|
@ -12565,7 +12567,6 @@ updateLoop:
|
||||||
// if in H-Blank, leave it and move to drawing mode
|
// if in H-Blank, leave it and move to drawing mode
|
||||||
io_registers[REG_VCOUNT] += 1;
|
io_registers[REG_VCOUNT] += 1;
|
||||||
UPDATE_REG(0x06, io_registers[REG_VCOUNT]);
|
UPDATE_REG(0x06, io_registers[REG_VCOUNT]);
|
||||||
|
|
||||||
graphics.lcdTicks += 1008;
|
graphics.lcdTicks += 1008;
|
||||||
io_registers[REG_DISPSTAT] &= 0xFFFD;
|
io_registers[REG_DISPSTAT] &= 0xFFFD;
|
||||||
if(io_registers[REG_VCOUNT] == 160)
|
if(io_registers[REG_VCOUNT] == 160)
|
||||||
|
@ -12643,6 +12644,8 @@ updateLoop:
|
||||||
io_registers[REG_IF] |= 2;
|
io_registers[REG_IF] |= 2;
|
||||||
UPDATE_REG(0x202, io_registers[REG_IF]);
|
UPDATE_REG(0x202, io_registers[REG_IF]);
|
||||||
}
|
}
|
||||||
|
if (scanlineCallback && scanlineCallbackLine == io_registers[REG_VCOUNT])
|
||||||
|
scanlineCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12936,6 +12939,9 @@ s16 *systemAudioFrameDest;
|
||||||
int *systemAudioFrameSamp;
|
int *systemAudioFrameSamp;
|
||||||
bool lagged;
|
bool lagged;
|
||||||
|
|
||||||
|
void (*scanlineCallback)();
|
||||||
|
int scanlineCallbackLine;
|
||||||
|
|
||||||
void systemDrawScreen (void)
|
void systemDrawScreen (void)
|
||||||
{
|
{
|
||||||
// upconvert 555->888 (TODO: BETTER)
|
// upconvert 555->888 (TODO: BETTER)
|
||||||
|
@ -13342,6 +13348,17 @@ template<bool isReader>bool SyncBatteryRam(NewState *ns)
|
||||||
return CPUReadByte(addr);
|
return CPUReadByte(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetScanlineCallback(void (*cb)(), int scanline)
|
||||||
|
{
|
||||||
|
// the sequence of calls in a frame will be:
|
||||||
|
// 160,161,...,227,0,1,...,160
|
||||||
|
// calls coincide with entering hblank, or something like that
|
||||||
|
if (scanline < 0 || scanline > 227)
|
||||||
|
cb = nullptr;
|
||||||
|
scanlineCallback = cb;
|
||||||
|
scanlineCallbackLine = scanline;
|
||||||
|
}
|
||||||
|
|
||||||
}; // class Gigazoid
|
}; // class Gigazoid
|
||||||
|
|
||||||
// zeroing mem operators: these are very important
|
// zeroing mem operators: these are very important
|
||||||
|
@ -13483,4 +13500,9 @@ EXPORT u8 SystemBusRead(Gigazoid *g, u32 addr)
|
||||||
return g->BusRead(addr);
|
return g->BusRead(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void SetScanlineCallback(Gigazoid *g, void (*cb)(), int scanline)
|
||||||
|
{
|
||||||
|
g->SetScanlineCallback(cb, scanline);
|
||||||
|
}
|
||||||
|
|
||||||
#include "optable.inc"
|
#include "optable.inc"
|
||||||
|
|
Loading…
Reference in New Issue