gambatte: more linkcable stuff. input isn't working, haven't figured out why yet. note: at the moment, any attempt to load a GB\GBC rom will bring up the dual core.

This commit is contained in:
goyuken 2012-12-29 15:48:30 +00:00
parent 689a5fac6e
commit 166110c609
5 changed files with 101 additions and 34 deletions

View File

@ -113,10 +113,8 @@ namespace BizHawk.Emulation.Consoles.GB
return (LibGambatte.gambatte_iscgb(GambatteState));
}
public void FrameAdvance(bool render, bool rendersound)
internal void FrameAdvancePrep()
{
uint nsamp = 35112; // according to gambatte docs, this is the nominal length of a frame in 2mhz clocks
Controller.UpdateControls(Frame++);
// update our local copy of the controller data
@ -155,21 +153,14 @@ namespace BizHawk.Emulation.Consoles.GB
else
tracecb = null;
LibGambatte.gambatte_settracecallback(GambatteState, tracecb);
}
LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref nsamp);
//Console.WriteLine("===");
internal void FrameAdvancePost()
{
// upload any modified data to the memory domains
foreach (var r in MemoryRefreshers)
r.RefreshRead();
if (rendersound)
soundbuffcontains = (int)nsamp;
else
soundbuffcontains = 0;
if (IsLagFrame)
LagCount++;
@ -177,6 +168,22 @@ namespace BizHawk.Emulation.Consoles.GB
endofframecallback(LibGambatte.gambatte_cpuread(GambatteState, 0xff40));
}
public void FrameAdvance(bool render, bool rendersound)
{
FrameAdvancePrep();
uint nsamp = 35112; // according to gambatte docs, this is the nominal length of a frame in 2mhz clocks
LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref nsamp);
if (rendersound)
soundbuffcontains = (int)nsamp;
else
soundbuffcontains = 0;
FrameAdvancePost();
}
/// <summary>
/// throw exception with intelligible message on some kinds of bad rom
/// </summary>
@ -720,11 +727,11 @@ namespace BizHawk.Emulation.Consoles.GB
/// <summary>
/// sample pairs before resampling
/// </summary>
short[] soundbuff = new short[(35112 + 2064) * 2];
internal short[] soundbuff = new short[(35112 + 2064) * 2];
/// <summary>
/// how many sample pairs are in soundbuff
/// </summary>
int soundbuffcontains = 0;
internal int soundbuffcontains = 0;
Sound.Utilities.SpeexResampler resampler;
Sound.Utilities.DCFilter dcfilter;

View File

@ -20,6 +20,10 @@ namespace BizHawk.Emulation.Consoles.GB
L = new Gameboy(new CoreComm(), leftinfo, leftrom);
R = new Gameboy(new CoreComm(), rightinfo, rightrom);
// connect link cable
LibGambatte.gambatte_linkstatus(L.GambatteState, 259);
LibGambatte.gambatte_linkstatus(R.GambatteState, 259);
L.Controller = LCont;
R.Controller = RCont;
@ -72,12 +76,81 @@ namespace BizHawk.Emulation.Consoles.GB
}
Frame++;
L.FrameAdvance(render, rendersound);
R.FrameAdvance(render, rendersound);
L.FrameAdvancePrep();
R.FrameAdvancePrep();
unsafe
{
fixed (int* leftvbuff = &VideoBuffer[0])
{
int* rightvbuff = leftvbuff + 160;
const int pitch = 160 * 2;
fixed (short* leftsbuff = L.soundbuff, rightsbuff = R.soundbuff)
{
const int step = 32; // could be 1024 for GB
int nL = 0;
int nR = 0;
for (int target = step; target <= 35112; target += step)
{
if (nL < target)
{
uint nsamp = (uint)(target - nL);
LibGambatte.gambatte_runfor(L.GambatteState, leftvbuff, pitch, leftsbuff + nL * 2, ref nsamp);
nL += (int)nsamp;
}
if (nR < target)
{
uint nsamp = (uint)(target - nR);
LibGambatte.gambatte_runfor(R.GambatteState, rightvbuff, pitch, rightsbuff + nR * 2, ref nsamp);
nR += (int)nsamp;
}
// poll link cable statuses
if (LibGambatte.gambatte_linkstatus(L.GambatteState, 256) != 0) // ClockTrigger
{
LibGambatte.gambatte_linkstatus(L.GambatteState, 257); // ack
int lo = LibGambatte.gambatte_linkstatus(L.GambatteState, 258); // GetOut
int ro = LibGambatte.gambatte_linkstatus(R.GambatteState, 258);
LibGambatte.gambatte_linkstatus(L.GambatteState, ro & 0xff); // ShiftIn
LibGambatte.gambatte_linkstatus(R.GambatteState, lo & 0xff); // ShiftIn
}
if (LibGambatte.gambatte_linkstatus(R.GambatteState, 256) != 0) // ClockTrigger
{
LibGambatte.gambatte_linkstatus(R.GambatteState, 257); // ack
int lo = LibGambatte.gambatte_linkstatus(L.GambatteState, 258); // GetOut
int ro = LibGambatte.gambatte_linkstatus(R.GambatteState, 258);
LibGambatte.gambatte_linkstatus(L.GambatteState, ro & 0xff); // ShiftIn
LibGambatte.gambatte_linkstatus(R.GambatteState, lo & 0xff); // ShiftIn
}
}
if (rendersound)
{
L.soundbuffcontains = nL;
R.soundbuffcontains = nR;
}
else
{
L.soundbuffcontains = 0;
R.soundbuffcontains = 0;
}
}
}
}
L.FrameAdvancePost();
R.FrameAdvancePost();
IsLagFrame = L.IsLagFrame && R.IsLagFrame;
if (IsLagFrame)
LagCount++;
BlitFrameBuffer();
}
public int Frame { get; private set; }
@ -217,21 +290,6 @@ namespace BizHawk.Emulation.Consoles.GB
public int BufferHeight { get { return 144; } }
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
void BlitFrameBuffer()
{
var lb = L.GetVideoBuffer();
var rb = R.GetVideoBuffer();
int destpos = 0;
for (int y = 0; y < 144; y++)
{
Buffer.BlockCopy(lb, 160 * 4 * y, VideoBuffer, destpos, 160 * 4);
destpos += 160 * 4;
Buffer.BlockCopy(rb, 160 * 4 * y, VideoBuffer, destpos, 160 * 4);
destpos += 160 * 4;
}
}
public void GetSamples(out short[] samples, out int nsamp)
{
// TODO

View File

@ -69,6 +69,8 @@ namespace BizHawk.Emulation.Consoles.GB
/// <returns>sample number at which the video frame was produced. -1 means no frame was produced.</returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_runfor(IntPtr core, int[] videobuf, int pitch, short[] soundbuf, ref uint samples);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern int gambatte_runfor(IntPtr core, int* videobuf, int pitch, short* soundbuf, ref uint samples);
/// <summary>
/// Reset to initial state.

View File

@ -2003,7 +2003,7 @@ namespace BizHawk.MultiClient
break;
case "GB":
case "GBC":
if (false) // DEBUG
if (true) // DEBUG
{
if (Global.Config.GB_ForceDMG) game.AddOption("ForceDMG");
if (Global.Config.GB_GBACGB) game.AddOption("GBACGB");