GGHawkLink:
-Seperate controller input -Fix lag indicator -Correct frame execution
This commit is contained in:
parent
4f17934d6c
commit
f08a521900
|
@ -61,88 +61,72 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
||||||
|
|
||||||
public void do_frame(IController controller, bool render, bool rendersound)
|
public void do_frame(IController controller, bool render, bool rendersound)
|
||||||
{
|
{
|
||||||
/*
|
L.start_pressed = controller.IsPressed("P1 Start");
|
||||||
L.do_controller_check();
|
R.start_pressed = controller.IsPressed("P2 Start");
|
||||||
R.do_controller_check();
|
|
||||||
|
L.FrameAdvancePrep();
|
||||||
// advance one full frame
|
R.FrameAdvancePrep();
|
||||||
for (int i = 0; i < 70224; i++)
|
|
||||||
|
int scanlinesPerFrame = 262;
|
||||||
|
|
||||||
|
L.Vdp.ScanLine = 0;
|
||||||
|
R.Vdp.ScanLine = 0;
|
||||||
|
|
||||||
|
for (int S = 0; S < scanlinesPerFrame; S++)
|
||||||
{
|
{
|
||||||
L.do_single_step();
|
L.Vdp.RenderCurrentScanline(render);
|
||||||
R.do_single_step();
|
R.Vdp.RenderCurrentScanline(render);
|
||||||
|
|
||||||
// the signal to shift out a bit is when serial_clock = 1
|
L.Vdp.ProcessFrameInterrupt();
|
||||||
if (((L.serialport.serial_clock == 1) || (L.serialport.serial_clock == 2)) && !do_r_next)
|
R.Vdp.ProcessFrameInterrupt();
|
||||||
|
|
||||||
|
L.Vdp.ProcessLineInterrupt();
|
||||||
|
R.Vdp.ProcessLineInterrupt();
|
||||||
|
|
||||||
|
// 512 cycles per line
|
||||||
|
for (int j = 0; j < 512; j++)
|
||||||
{
|
{
|
||||||
if (LinkConnected)
|
L.Cpu.ExecuteOne();
|
||||||
{
|
R.Cpu.ExecuteOne();
|
||||||
L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80));
|
|
||||||
|
|
||||||
if ((R.serialport.clk_rate == -1) && R.serialport.serial_start)
|
/*
|
||||||
{
|
*
|
||||||
R.serialport.serial_clock = L.serialport.serial_clock;
|
* Linking code goes here
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we hit a frame boundary, update video
|
if (S == scanlinesPerFrame - 1)
|
||||||
if (L.vblank_rise)
|
|
||||||
{
|
{
|
||||||
buff_L = L.GetVideoBuffer();
|
L.Vdp.ProcessGGScreen();
|
||||||
L.vblank_rise = false;
|
R.Vdp.ProcessGGScreen();
|
||||||
FillVideoBuffer();
|
|
||||||
|
L.Vdp.ProcessOverscan();
|
||||||
|
R.Vdp.ProcessOverscan();
|
||||||
}
|
}
|
||||||
if (R.vblank_rise)
|
|
||||||
{
|
L.Vdp.ScanLine++;
|
||||||
buff_R = R.GetVideoBuffer();
|
R.Vdp.ScanLine++;
|
||||||
R.vblank_rise = false;
|
}
|
||||||
FillVideoBuffer();
|
|
||||||
}
|
L.FrameAdvancePost();
|
||||||
}
|
R.FrameAdvancePost();
|
||||||
*/
|
|
||||||
L.FrameAdvance(controller, render, rendersound);
|
|
||||||
R.FrameAdvance(controller, render, rendersound);
|
|
||||||
|
|
||||||
buff_L = L.Vdp.GetVideoBuffer();
|
buff_L = L.Vdp.GetVideoBuffer();
|
||||||
buff_R = R.Vdp.GetVideoBuffer();
|
buff_R = R.Vdp.GetVideoBuffer();
|
||||||
|
|
||||||
FillVideoBuffer();
|
FillVideoBuffer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetControllerState(IController controller)
|
public void GetControllerState(IController controller)
|
||||||
{
|
{
|
||||||
InputCallbacks.Call();
|
InputCallbacks.Call();
|
||||||
//L.controller_state = _controllerDeck.ReadPort1(controller);
|
L.cntr_rd_0 = (byte)(controller.IsPressed("P1 Start") ? 0x7F : 0xFF);
|
||||||
//R.controller_state = _controllerDeck.ReadPort2(controller);
|
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;
|
public int Frame => _frame;
|
||||||
|
|
|
@ -65,6 +65,9 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
||||||
HardReset();
|
HardReset();
|
||||||
|
|
||||||
LinkConnected = _cableconnected;
|
LinkConnected = _cableconnected;
|
||||||
|
|
||||||
|
L.stand_alone = false;
|
||||||
|
R.stand_alone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HardReset()
|
public void HardReset()
|
||||||
|
|
|
@ -47,35 +47,27 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
|
||||||
|
|
||||||
if (c.IsPressed(Definition.BoolButtons[0]))
|
if (c.IsPressed(Definition.BoolButtons[0]))
|
||||||
{
|
{
|
||||||
result -= 4;
|
result &= 0xFE;
|
||||||
}
|
}
|
||||||
if (c.IsPressed(Definition.BoolButtons[1]))
|
if (c.IsPressed(Definition.BoolButtons[1]))
|
||||||
{
|
{
|
||||||
result -= 8;
|
result &= 0xFD;
|
||||||
}
|
}
|
||||||
if (c.IsPressed(Definition.BoolButtons[2]))
|
if (c.IsPressed(Definition.BoolButtons[2]))
|
||||||
{
|
{
|
||||||
result -= 2;
|
result &= 0xFB;
|
||||||
}
|
}
|
||||||
if (c.IsPressed(Definition.BoolButtons[3]))
|
if (c.IsPressed(Definition.BoolButtons[3]))
|
||||||
{
|
{
|
||||||
result -= 1;
|
result &= 0xF7;
|
||||||
}
|
}
|
||||||
if (c.IsPressed(Definition.BoolButtons[4]))
|
if (c.IsPressed(Definition.BoolButtons[4]))
|
||||||
{
|
{
|
||||||
result -= 128;
|
result &= 0xEF;
|
||||||
}
|
}
|
||||||
if (c.IsPressed(Definition.BoolButtons[5]))
|
if (c.IsPressed(Definition.BoolButtons[5]))
|
||||||
{
|
{
|
||||||
result -= 64;
|
result &= 0xDF;
|
||||||
}
|
|
||||||
if (c.IsPressed(Definition.BoolButtons[6]))
|
|
||||||
{
|
|
||||||
result -= 32;
|
|
||||||
}
|
|
||||||
if (c.IsPressed(Definition.BoolButtons[7]))
|
|
||||||
{
|
|
||||||
result -= 16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -90,7 +90,44 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
return true;
|
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";
|
public string SystemId => "SMS";
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
ser.Sync("Controller1SelectHigh", ref Controller1SelectHigh);
|
ser.Sync("Controller1SelectHigh", ref Controller1SelectHigh);
|
||||||
ser.Sync("ControllerSelect2High", ref Controller2SelectHigh);
|
ser.Sync("ControllerSelect2High", ref Controller2SelectHigh);
|
||||||
ser.Sync("LatchLightPhaser", ref LatchLightPhaser);
|
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)
|
if (SaveRAM != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -592,6 +592,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_lagged = false;
|
||||||
|
|
||||||
byte value = 0xFF;
|
byte value = 0xFF;
|
||||||
if ((_controller.IsPressed("Pause") && !IsGameGear) ||
|
if ((_controller.IsPressed("Pause") && !IsGameGear) ||
|
||||||
(_controller.IsPressed("P1 Start") && IsGameGear_C))
|
(_controller.IsPressed("P1 Start") && IsGameGear_C))
|
||||||
|
|
|
@ -93,7 +93,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
OnExecFetch = OnExecMemory
|
OnExecFetch = OnExecMemory
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (game["GG_in_SMS"])
|
if (game["GG_in_SMS"])
|
||||||
{
|
{
|
||||||
// skip setting the BIOS because this is a game gear game that puts the system
|
// 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 byte ForceStereoByte = 0xAD;
|
||||||
private bool IsGame3D = false;
|
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; }
|
private ITraceable Tracer { get; set; }
|
||||||
|
|
||||||
|
@ -336,7 +341,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
|
|
||||||
switch (port)
|
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 0x01: return Port01;
|
||||||
case 0x02: return Port02;
|
case 0x02: return Port02;
|
||||||
case 0x03: return 0x00;
|
case 0x03: return 0x00;
|
||||||
|
@ -364,9 +369,9 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
switch (port)
|
switch (port)
|
||||||
{
|
{
|
||||||
case 0xC0:
|
case 0xC0:
|
||||||
case 0xDC: return ReadControls1();
|
case 0xDC: if (stand_alone) { return ReadControls1(); } else { _lagged = false; return cntr_rd_1; }
|
||||||
case 0xC1:
|
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 0xDE: return PortDEEnabled ? PortDE : (byte)0xFF;
|
||||||
case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte)0xFF;
|
case 0xF2: return HasYM2413 ? YM2413.DetectionValue : (byte)0xFF;
|
||||||
default: return 0xFF;
|
default: return 0xFF;
|
||||||
|
@ -403,8 +408,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
else if (port == 0xF2 && HasYM2413) YM2413.DetectionValue = value;
|
else if (port == 0xF2 && HasYM2413) YM2413.DetectionValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _region;
|
public string _region;
|
||||||
private string RegionStr
|
public string RegionStr
|
||||||
{
|
{
|
||||||
get { return _region; }
|
get { return _region; }
|
||||||
set
|
set
|
||||||
|
|
|
@ -337,7 +337,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessFrameInterrupt()
|
public void ProcessFrameInterrupt()
|
||||||
{
|
{
|
||||||
if (ScanLine == FrameHeight + 1)
|
if (ScanLine == FrameHeight + 1)
|
||||||
{
|
{
|
||||||
|
@ -352,7 +352,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessLineInterrupt()
|
public void ProcessLineInterrupt()
|
||||||
{
|
{
|
||||||
if (ScanLine <= FrameHeight)
|
if (ScanLine <= FrameHeight)
|
||||||
{
|
{
|
||||||
|
@ -383,15 +383,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
ProcessLineInterrupt();
|
ProcessLineInterrupt();
|
||||||
Sms.ProcessLineControls();
|
Sms.ProcessLineControls();
|
||||||
|
|
||||||
//Console.Write(Cpu.cur_instr.Length);
|
|
||||||
//Console.Write(" ");
|
|
||||||
//Console.WriteLine(Cpu.instr_pntr);
|
|
||||||
for (int j = 0; j < IPeriod; j++)
|
for (int j = 0; j < IPeriod; j++)
|
||||||
{
|
{
|
||||||
Cpu.ExecuteOne();
|
Cpu.ExecuteOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ScanLine == scanlinesPerFrame - 1)
|
if (ScanLine == scanlinesPerFrame - 1)
|
||||||
{
|
{
|
||||||
ProcessGGScreen();
|
ProcessGGScreen();
|
||||||
|
|
Loading…
Reference in New Issue