SubGBHawk: add

This commit is contained in:
alyosha-tas 2020-02-23 09:54:42 -05:00
parent e1128e4150
commit f0692111d7
11 changed files with 327 additions and 8 deletions

View File

@ -1042,9 +1042,16 @@ namespace BizHawk.Client.Common
case "GB":
if (!Global.Config.GbAsSgb)
{
core = Global.Config.GbUseGbHawk
if (Global.Config.UseSubGBHawk)
{
core = CoreInventory.Instance["GB", "SubGBHawk"];
}
else
{
core = Global.Config.GbUseGbHawk
? CoreInventory.Instance["GB", "GBHawk"]
: CoreInventory.Instance["GB", "Gambatte"];
}
}
else
{
@ -1064,9 +1071,16 @@ namespace BizHawk.Client.Common
case "GBC":
if (!Global.Config.GbAsSgb)
{
core = Global.Config.GbUseGbHawk
if (Global.Config.UseSubGBHawk)
{
core = CoreInventory.Instance["GB", "SubGBHawk"];
}
else
{
core = Global.Config.GbUseGbHawk
? CoreInventory.Instance["GBC", "GBHawk"]
: CoreInventory.Instance["GBC", "Gambatte"];
}
}
else
{

View File

@ -306,6 +306,7 @@ namespace BizHawk.Client.Common
// it hasn't been absorbed into the new system
public bool GbAsSgb { get; set; }
public bool UseSubNESHawk { get; set; }
public bool UseSubGBHawk { get; set; }
public bool NesInQuickNes { get; set; } = true;
public bool SnesInSnes9x { get; set; } = true;
public bool GbaUsemGba { get; set; } = true;

View File

@ -187,6 +187,7 @@
this.NesCoreMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator38 = new System.Windows.Forms.ToolStripSeparator();
this.SubNesHawkMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SubGBHawkMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CoreSNESSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.Coresnes9xMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CorebsnesMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -1849,6 +1850,13 @@
this.SubNesHawkMenuItem.Text = "SubNesHawk (Experimental)";
this.SubNesHawkMenuItem.Click += new System.EventHandler(this.SubNesCorePick_Click);
//
// SubGBHawkMenuItem
//
this.SubGBHawkMenuItem.Name = "SubGBHawkMenuItem";
this.SubGBHawkMenuItem.Size = new System.Drawing.Size(209, 22);
this.SubGBHawkMenuItem.Text = "SubGBHawk (Experimental)";
this.SubGBHawkMenuItem.Click += new System.EventHandler(this.SubGBCorePick_Click);
//
// CoreSNESSubMenu
//
this.CoreSNESSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -1925,7 +1933,9 @@
//
this.GBCoreSubmenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.GBGambatteMenuItem,
this.GBGBHawkMenuItem});
this.GBGBHawkMenuItem,
this.toolStripSeparator38,
this.SubGBHawkMenuItem});
this.GBCoreSubmenu.Name = "GBCoreSubmenu";
this.GBCoreSubmenu.Size = new System.Drawing.Size(223, 22);
this.GBCoreSubmenu.Text = "GB";
@ -4451,6 +4461,7 @@
private System.Windows.Forms.ToolStripMenuItem cpcd1ToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem AmstradCPCNonSyncSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SubNesHawkMenuItem;
private System.Windows.Forms.ToolStripMenuItem SubGBHawkMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator38;
private System.Windows.Forms.ToolStripMenuItem arcadeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem2;

View File

@ -1228,6 +1228,16 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SubGBCorePick_Click(object sender, EventArgs e)
{
Config.UseSubGBHawk ^= true;
if (!Emulator.IsNull())
{
FlagNeedsReboot();
}
}
private void CoreSNESSubMenu_DropDownOpened(object sender, EventArgs e)
{
Coresnes9xMenuItem.Checked = Config.SnesInSnes9x;
@ -1269,6 +1279,7 @@ namespace BizHawk.Client.EmuHawk
{
GBGambatteMenuItem.Checked = !Config.GbUseGbHawk;
GBGBHawkMenuItem.Checked = Config.GbUseGbHawk;
SubGBHawkMenuItem.Checked = Config.UseSubGBHawk;
}
private void SgbCorePick_Click(object sender, EventArgs e)
@ -1284,6 +1295,7 @@ namespace BizHawk.Client.EmuHawk
private void GBCorePick_Click(object sender, EventArgs e)
{
Config.GbUseGbHawk ^= true;
Config.UseSubGBHawk = false;
// TODO: only flag if one of these cores
if (!Emulator.IsNull())
{

View File

@ -317,7 +317,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
_vidbuffer[i] = (int)color_palette[0];
}
}
for (int j = 0; j < frame_buffer.Length; j++) { frame_buffer[j] = _vidbuffer[j]; }
ppu.blank_frame = false;

View File

@ -341,7 +341,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0x1E: mapper = new MapperMBC5(); mppr = "MBC5"; has_bat = true; break;
case 0x20: mapper = new MapperMBC6(); mppr = "MBC6"; break;
case 0x22: mapper = new MapperMBC7(); mppr = "MBC7"; has_bat = true; break;
case 0xFC: mapper = new MapperCamera(); mppr = "CAM"; break;
case 0xFC: mapper = new MapperCamera(); mppr = "CAM"; has_bat = true; break;
case 0xFD: mapper = new MapperTAMA5(); mppr = "TAMA5"; has_bat = true; break;
case 0xFE: mapper = new MapperHuC3(); mppr = "HuC3"; break;
case 0xFF: mapper = new MapperHuC1(); mppr = "HuC1"; break;

View File

@ -1,5 +1,6 @@
using BizHawk.Common;
using BizHawk.Emulation.Cores.Components.LR35902;
using System;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
@ -22,10 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
RAM_enable = false;
ROM_mask = Core._rom.Length / 0x4000 - 1;
RAM_mask = 0;
RAM_mask = Core.cart_RAM.Length / 0x2000 - 1;
if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; }
regs_enable = false;
}

View File

@ -0,0 +1,143 @@
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
{
public partial class SubGBHawk : IEmulator
{
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition => _GBCore.ControllerDefinition;
public bool FrameAdvance(IController controller, bool render, bool renderSound)
{
//Console.WriteLine("-----------------------FRAME-----------------------");
//Update the color palette if a setting changed
if (GetSettings().Palette == GBHawk.GBHawk.GBSettings.PaletteType.BW)
{
_GBCore.color_palette[0] = GBHawk.GBHawk.color_palette_BW[0];
_GBCore.color_palette[1] = GBHawk.GBHawk.color_palette_BW[1];
_GBCore.color_palette[2] = GBHawk.GBHawk.color_palette_BW[2];
_GBCore.color_palette[3] = GBHawk.GBHawk.color_palette_BW[3];
}
else
{
_GBCore.color_palette[0] = GBHawk.GBHawk.color_palette_Gr[0];
_GBCore.color_palette[1] = GBHawk.GBHawk.color_palette_Gr[1];
_GBCore.color_palette[2] = GBHawk.GBHawk.color_palette_Gr[2];
_GBCore.color_palette[3] = GBHawk.GBHawk.color_palette_Gr[3];
}
if (_tracer.Enabled)
{
_GBCore.cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
_GBCore.cpu.TraceCallback = null;
}
_frame++;
reset_frame = false;
if (controller.IsPressed("P1 Power"))
{
reset_frame = true;
}
input_frame_length = controller.GetFloat("Input Cycle");
input_frame_length_int = (int)Math.Floor(input_frame_length);
if (input_frame_length_int == 0)
{
input_frame_length_int = 70224;
}
pass_a_frame = false;
InputCallbacks.Call();
DoFrame(controller);
bool ret = pass_a_frame;
if (pass_a_frame) { frame_cycle = 0; }
current_cycle = 0;
_isLag = pass_a_frame;
if (_isLag)
{
_lagCount++;
VBL_CNT++;
}
reset_frame = false;
return ret;
}
private bool stop_cur_frame;
private bool pass_new_input;
private bool pass_a_frame;
private bool reset_frame;
private int current_cycle;
private int frame_cycle;
private float input_frame_length;
private int input_frame_length_int;
private void DoFrame(IController controller)
{
stop_cur_frame = false;
_GBCore.GetControllerState(controller);
_GBCore.do_controller_check();
while (!stop_cur_frame)
{
_GBCore.do_single_step();
if (reset_frame)
{
HardReset();
reset_frame = false;
stop_cur_frame |= true;
pass_a_frame |= true;
}
current_cycle++;
frame_cycle++;
if (frame_cycle == 70224)
{
stop_cur_frame |= true;
pass_a_frame |= true;
}
if (current_cycle == input_frame_length_int)
{
stop_cur_frame |= true;
}
if (_GBCore.vblank_rise)
{
_GBCore.SendVideoBuffer();
_GBCore.vblank_rise = false;
}
}
}
public int Frame => _frame;
public string SystemId => "GB";
public bool DeterministicEmulation => _GBCore.DeterministicEmulation;
public void ResetCounters()
{
_frame = 0;
_lagCount = 0;
_isLag = false;
}
public CoreComm CoreComm => _GBCore.CoreComm;
public void Dispose() => _GBCore.Dispose();
}
}

View File

@ -0,0 +1,24 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
{
public partial class SubGBHawk : IInputPollable
{
public int LagCount
{
get => _lagCount;
set => _lagCount = value;
}
public bool IsLagFrame
{
get => _isLag;
set => _isLag = value;
}
public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem();
public bool _isLag = true;
private int _lagCount;
}
}

View File

@ -0,0 +1,50 @@
using System.IO;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
{
public partial class SubGBHawk : IStatable
{
private readonly IStatable _GBStatable;
public void SaveStateBinary(BinaryWriter bw)
{
_GBStatable.SaveStateBinary(bw);
// other variables
SyncState(new Serializer(bw));
}
public void LoadStateBinary(BinaryReader br)
{
_GBStatable.LoadStateBinary(br);
// other variables
SyncState(new Serializer(br));
}
public byte[] SaveStateBinary()
{
using var ms = new MemoryStream();
using var bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
private void SyncState(Serializer ser)
{
ser.Sync("Lag", ref _lagCount);
ser.Sync("Frame", ref _frame);
ser.Sync("IsLag", ref _isLag);
ser.Sync(nameof(pass_a_frame), ref pass_a_frame);
ser.Sync(nameof(reset_frame), ref reset_frame);
ser.Sync(nameof(pass_new_input), ref pass_new_input);
ser.Sync(nameof(current_cycle), ref current_cycle);
ser.Sync(nameof(frame_cycle), ref frame_cycle);
ser.Sync(nameof(input_frame_length), ref input_frame_length);
ser.Sync(nameof(input_frame_length_int), ref input_frame_length_int);
ser.Sync(nameof(VBL_CNT), ref VBL_CNT);
}
}
}

View File

@ -0,0 +1,66 @@
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
{
[Core(
"SubGBHawk",
"",
isPorted: false,
isReleased: true)]
[ServiceNotApplicable(new [] { typeof(IDriveLight) })]
public partial class SubGBHawk : IEmulator, IStatable, IInputPollable,
ISettable<GBHawk.GBHawk.GBSettings, GBHawk.GBHawk.GBSyncSettings>
{
[CoreConstructor(new[] { "GB", "GBC" })]
public SubGBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
{
var subGBSettings = (GBHawk.GBHawk.GBSettings)settings ?? new GBHawk.GBHawk.GBSettings();
var subGBSyncSettings = (GBHawk.GBHawk.GBSyncSettings)syncSettings ?? new GBHawk.GBHawk.GBSyncSettings();
_GBCore = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify) { CoreFileProvider = comm.CoreFileProvider },
game, rom, subGBSettings, subGBSyncSettings);
HardReset();
current_cycle = 0;
VBL_CNT = 0;
_GBStatable = _GBCore.ServiceProvider.GetService<IStatable>();
var ser = new BasicServiceProvider(this);
ServiceProvider = ser;
ser.Register(_GBCore.ServiceProvider.GetService<IVideoProvider>());
ser.Register(_GBCore.ServiceProvider.GetService<ISoundProvider>());
ser.Register(_GBCore.ServiceProvider.GetService<ITraceable>());
ser.Register(_GBCore.ServiceProvider.GetService<IMemoryDomains>());
ser.Register(_GBCore.ServiceProvider.GetService<ISaveRam>());
ser.Register(_GBCore.ServiceProvider.GetService<IDebuggable>());
ser.Register(_GBCore.ServiceProvider.GetService<IRegionable>());
ser.Register(_GBCore.ServiceProvider.GetService<ICodeDataLogger>());
_tracer = new TraceBuffer { Header = _GBCore.cpu.TraceHeader };
ser.Register(_tracer);
_GBCore.ControllerDefinition.FloatControls.Add("Input Cycle");
_GBCore.ControllerDefinition.FloatRanges.Add(new ControllerDefinition.FloatRange(0, 70224, 70224));
}
public GBHawk.GBHawk _GBCore;
// needed for movies to accurately calculate timing
public int VBL_CNT;
public void HardReset() => _GBCore.HardReset();
private int _frame;
private readonly ITraceable _tracer;
public GBHawk.GBHawk.GBSettings GetSettings() => _GBCore.GetSettings();
public GBHawk.GBHawk.GBSyncSettings GetSyncSettings() => _GBCore.GetSyncSettings();
public bool PutSettings(GBHawk.GBHawk.GBSettings o) => _GBCore.PutSettings(o);
public bool PutSyncSettings(GBHawk.GBHawk.GBSyncSettings o) => _GBCore.PutSyncSettings(o);
}
}