GGHawkLink:

-Seperate controller input
-Fix lag indicator
-Correct frame execution
This commit is contained in:
alyosha-tas 2019-02-09 11:45:29 -06:00
parent 4f17934d6c
commit f08a521900
8 changed files with 116 additions and 92 deletions

View File

@ -61,88 +61,72 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
public void do_frame(IController controller, bool render, bool rendersound)
{
/*
L.do_controller_check();
R.do_controller_check();
// advance one full frame
for (int i = 0; i < 70224; i++)
L.start_pressed = controller.IsPressed("P1 Start");
R.start_pressed = controller.IsPressed("P2 Start");
L.FrameAdvancePrep();
R.FrameAdvancePrep();
int scanlinesPerFrame = 262;
L.Vdp.ScanLine = 0;
R.Vdp.ScanLine = 0;
for (int S = 0; S < scanlinesPerFrame; S++)
{
L.do_single_step();
R.do_single_step();
L.Vdp.RenderCurrentScanline(render);
R.Vdp.RenderCurrentScanline(render);
// the signal to shift out a bit is when serial_clock = 1
if (((L.serialport.serial_clock == 1) || (L.serialport.serial_clock == 2)) && !do_r_next)
L.Vdp.ProcessFrameInterrupt();
R.Vdp.ProcessFrameInterrupt();
L.Vdp.ProcessLineInterrupt();
R.Vdp.ProcessLineInterrupt();
// 512 cycles per line
for (int j = 0; j < 512; j++)
{
if (LinkConnected)
{
L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80));
L.Cpu.ExecuteOne();
R.Cpu.ExecuteOne();
if ((R.serialport.clk_rate == -1) && R.serialport.serial_start)
{
R.serialport.serial_clock = L.serialport.serial_clock;
R.serialport.send_external_bit((byte)(R.serialport.serial_data & 0x80));
R.serialport.coming_in = L.serialport.going_out;
}
L.serialport.coming_in = R.serialport.going_out;
}
}
else if ((R.serialport.serial_clock == 1) || (R.serialport.serial_clock == 2))
{
do_r_next = false;
if (LinkConnected)
{
R.serialport.send_external_bit((byte)(R.serialport.serial_data & 0x80));
if ((L.serialport.clk_rate == -1) && L.serialport.serial_start)
{
L.serialport.serial_clock = R.serialport.serial_clock;
L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80));
L.serialport.coming_in = R.serialport.going_out;
}
R.serialport.coming_in = L.serialport.going_out;
}
if (R.serialport.serial_clock == 2) { do_r_next = true; }
}
else
{
do_r_next = false;
/*
*
* Linking code goes here
*
*/
}
// if we hit a frame boundary, update video
if (L.vblank_rise)
if (S == scanlinesPerFrame - 1)
{
buff_L = L.GetVideoBuffer();
L.vblank_rise = false;
FillVideoBuffer();
L.Vdp.ProcessGGScreen();
R.Vdp.ProcessGGScreen();
L.Vdp.ProcessOverscan();
R.Vdp.ProcessOverscan();
}
if (R.vblank_rise)
{
buff_R = R.GetVideoBuffer();
R.vblank_rise = false;
FillVideoBuffer();
}
}
*/
L.FrameAdvance(controller, render, rendersound);
R.FrameAdvance(controller, render, rendersound);
L.Vdp.ScanLine++;
R.Vdp.ScanLine++;
}
L.FrameAdvancePost();
R.FrameAdvancePost();
buff_L = L.Vdp.GetVideoBuffer();
buff_R = R.Vdp.GetVideoBuffer();
FillVideoBuffer();
}
public void GetControllerState(IController controller)
{
InputCallbacks.Call();
//L.controller_state = _controllerDeck.ReadPort1(controller);
//R.controller_state = _controllerDeck.ReadPort2(controller);
L.cntr_rd_0 = (byte)(controller.IsPressed("P1 Start") ? 0x7F : 0xFF);
L.cntr_rd_1 = _controllerDeck.ReadPort1(controller);
L.cntr_rd_2 = 0xFF;
R.cntr_rd_0 = (byte)(controller.IsPressed("P2 Start") ? 0x7F : 0xFF);
R.cntr_rd_1 = _controllerDeck.ReadPort2(controller);
R.cntr_rd_2 = 0xFF;
}
public int Frame => _frame;

View File

@ -65,6 +65,9 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
HardReset();
LinkConnected = _cableconnected;
L.stand_alone = false;
R.stand_alone = false;
}
public void HardReset()

View File

@ -47,35 +47,27 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
if (c.IsPressed(Definition.BoolButtons[0]))
{
result -= 4;
result &= 0xFE;
}
if (c.IsPressed(Definition.BoolButtons[1]))
{
result -= 8;
result &= 0xFD;
}
if (c.IsPressed(Definition.BoolButtons[2]))
{
result -= 2;
result &= 0xFB;
}
if (c.IsPressed(Definition.BoolButtons[3]))
{
result -= 1;
result &= 0xF7;
}
if (c.IsPressed(Definition.BoolButtons[4]))
{
result -= 128;
result &= 0xEF;
}
if (c.IsPressed(Definition.BoolButtons[5]))
{
result -= 64;
}
if (c.IsPressed(Definition.BoolButtons[6]))
{
result -= 32;
}
if (c.IsPressed(Definition.BoolButtons[7]))
{
result -= 16;
result &= 0xDF;
}
return result;

View File

@ -90,7 +90,44 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return true;
}
public int Frame => _frame;
// Used for GG linked play
public void FrameAdvancePrep()
{
_lagged = true;
_frame++;
PSG.BeginFrame(Cpu.TotalExecutedCycles);
if (Tracer.Enabled)
{
Cpu.TraceCallback = s => Tracer.Put(s);
}
else
{
Cpu.TraceCallback = null;
}
if (!IsGameGear && IsGameGear_C)
{
Cpu.NonMaskableInterrupt = start_pressed;
}
}
// Used for GG linked play
public void FrameAdvancePost()
{
PSG.EndFrame(Cpu.TotalExecutedCycles);
if (_lagged)
{
_lagCount++;
_isLag = true;
}
else
{
_isLag = false;
}
}
public int Frame => _frame;
public string SystemId => "SMS";

View File

@ -70,6 +70,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
ser.Sync("Controller1SelectHigh", ref Controller1SelectHigh);
ser.Sync("ControllerSelect2High", ref Controller2SelectHigh);
ser.Sync("LatchLightPhaser", ref LatchLightPhaser);
ser.Sync("start_pressed", ref start_pressed);
ser.Sync("cntr_rd_0", ref cntr_rd_0);
ser.Sync("cntr_rd_1", ref cntr_rd_1);
ser.Sync("cntr_rd_2", ref cntr_rd_2);
ser.Sync("stand_alone", ref stand_alone);
if (SaveRAM != null)
{

View File

@ -592,6 +592,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return 0xFF;
}
_lagged = false;
byte value = 0xFF;
if ((_controller.IsPressed("Pause") && !IsGameGear) ||
(_controller.IsPressed("P1 Start") && IsGameGear_C))

View File

@ -93,7 +93,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
OnExecFetch = OnExecMemory
};
if (game["GG_in_SMS"])
{
// skip setting the BIOS because this is a game gear game that puts the system
@ -254,8 +253,14 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
private byte ForceStereoByte = 0xAD;
private bool IsGame3D = false;
public DisplayType Region { get; set; }
// Linked Play Only
public bool start_pressed;
public byte cntr_rd_0;
public byte cntr_rd_1;
public byte cntr_rd_2;
public bool stand_alone = true;
public DisplayType Region { get; set; }
private ITraceable Tracer { get; set; }
@ -336,7 +341,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
switch (port)
{
case 0x00: return ReadPort0();
case 0x00: if (stand_alone) { return ReadPort0(); } else { _lagged = false; return cntr_rd_0; }
case 0x01: return Port01;
case 0x02: return Port02;
case 0x03: return 0x00;
@ -364,9 +369,9 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
switch (port)
{
case 0xC0:
case 0xDC: return ReadControls1();
case 0xDC: if (stand_alone) { return ReadControls1(); } else { _lagged = false; return cntr_rd_1; }
case 0xC1:
case 0xDD: return ReadControls2();
case 0xDD: if (stand_alone) { return ReadControls2(); } else { _lagged = false; return cntr_rd_2; }
case 0xDE: return PortDEEnabled ? PortDE : (byte)0xFF;
case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte)0xFF;
default: return 0xFF;
@ -403,8 +408,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
else if (port == 0xF2 && HasYM2413) YM2413.DetectionValue = value;
}
private string _region;
private string RegionStr
public string _region;
public string RegionStr
{
get { return _region; }
set

View File

@ -337,7 +337,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
}
void ProcessFrameInterrupt()
public void ProcessFrameInterrupt()
{
if (ScanLine == FrameHeight + 1)
{
@ -352,7 +352,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
void ProcessLineInterrupt()
public void ProcessLineInterrupt()
{
if (ScanLine <= FrameHeight)
{
@ -383,15 +383,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
ProcessLineInterrupt();
Sms.ProcessLineControls();
//Console.Write(Cpu.cur_instr.Length);
//Console.Write(" ");
//Console.WriteLine(Cpu.instr_pntr);
for (int j = 0; j < IPeriod; j++)
{
Cpu.ExecuteOne();
}
if (ScanLine == scanlinesPerFrame - 1)
{
ProcessGGScreen();