From 6e1932c8bd914b96d7cc4dc19c9f551c544aeb96 Mon Sep 17 00:00:00 2001 From: goyuken Date: Mon, 29 Sep 2014 18:53:53 +0000 Subject: [PATCH] lynx: lag indicator --- .../Consoles/Atari/lynx/LibLynx.cs | 2 +- .../Consoles/Atari/lynx/Lynx.cs | 4 +++- lynx/cinterface.cpp | 4 ++-- lynx/susie.cpp | 2 ++ lynx/susie.h | 3 ++- lynx/system.cpp | 5 ++++- lynx/system.h | 4 ++-- output/dll/bizlynx.dll | Bin 61440 -> 61440 bytes 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/LibLynx.cs b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/LibLynx.cs index 242410739c..f796d5272f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/LibLynx.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/LibLynx.cs @@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx public static extern void Reset(IntPtr s); [DllImport(dllname, CallingConvention = cc)] - public static extern void Advance(IntPtr s, Buttons buttons, int[] vbuff, short[] sbuff, ref int sbuffsize); + public static extern bool Advance(IntPtr s, Buttons buttons, int[] vbuff, short[] sbuff, ref int sbuffsize); [DllImport(dllname, CallingConvention = cc)] public static extern bool GetSaveRamPtr(IntPtr s, out int size, out IntPtr data); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs index 8be37c98ff..8ea08b84d5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs @@ -111,8 +111,10 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx LibLynx.Reset(Core); int samples = soundbuff.Length; - LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples); + IsLagFrame = LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples); numsamp = samples / 2; // sound provider wants number of sample pairs + if (IsLagFrame) + LagCount++; } public int Frame { get; private set; } diff --git a/lynx/cinterface.cpp b/lynx/cinterface.cpp index 872d3851c7..9edf3d7699 100644 --- a/lynx/cinterface.cpp +++ b/lynx/cinterface.cpp @@ -32,9 +32,9 @@ EXPORT void Reset(CSystem *s) s->Reset(); } -EXPORT void Advance(CSystem *s, int buttons, uint32 *vbuff, int16 *sbuff, int *sbuffsize) +EXPORT int Advance(CSystem *s, int buttons, uint32 *vbuff, int16 *sbuff, int *sbuffsize) { - s->Advance(buttons, vbuff, sbuff, *sbuffsize); + return s->Advance(buttons, vbuff, sbuff, *sbuffsize); } EXPORT int GetSaveRamPtr(CSystem *s, int *size, uint8 **data) diff --git a/lynx/susie.cpp b/lynx/susie.cpp index 9615efc292..22ba6872da 100644 --- a/lynx/susie.cpp +++ b/lynx/susie.cpp @@ -2076,6 +2076,7 @@ uint8 CSusie::Peek(uint32 addr) retval= Modified.Byte; } // TRACE_SUSIE2("Peek(JOYSTICK)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC()); + lagged = false; return retval; break; @@ -2083,6 +2084,7 @@ uint8 CSusie::Peek(uint32 addr) case (SWITCHES&0xff): retval=mSWITCHES.Byte; // TRACE_SUSIE2("Peek(SWITCHES)=$%02x at PC=$%04x",retval,mSystem.mCpu->GetPC()); + lagged = false; return retval; // Cartridge reading ports diff --git a/lynx/susie.h b/lynx/susie.h index ccd03132d3..470b56e904 100644 --- a/lynx/susie.h +++ b/lynx/susie.h @@ -324,9 +324,10 @@ class CSusie : public CLynxBase uint32 ObjectSize(void) {return SUSIE_SIZE;}; void SetButtonData(uint32 data) {mJOYSTICK.Byte=(uint8)data;mSWITCHES.Byte=(uint8)(data>>8);}; - uint32 GetButtonData(void) {return mJOYSTICK.Byte+(mSWITCHES.Byte<<8);}; + // uint32 GetButtonData(void) {return mJOYSTICK.Byte+(mSWITCHES.Byte<<8);}; uint32 PaintSprites(void); + bool lagged; // set to false whenever joystick/switches are read private: void DoMathDivide(void); diff --git a/lynx/system.cpp b/lynx/system.cpp index 833806806d..9114fd29ec 100644 --- a/lynx/system.cpp +++ b/lynx/system.cpp @@ -153,12 +153,13 @@ static int Load(MDFNFILE *fp) } */ -void CSystem::Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize) +bool CSystem::Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize) { // this check needs to occur at least once every 250 million cycles or better mMikie->CheckWrap(); SetButtonData(buttons); + mSusie->lagged = true; uint32 start = gSystemCycleCount; @@ -183,6 +184,8 @@ void CSystem::Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize) mMikie->mikbuf.end_frame((gSystemCycleCount - start) >> 2); sbuffsize = mMikie->mikbuf.read_samples(sbuff, sbuffsize); + + return mSusie->lagged; } diff --git a/lynx/system.h b/lynx/system.h index ddbf987dc4..bcaf6b8f36 100644 --- a/lynx/system.h +++ b/lynx/system.h @@ -139,7 +139,7 @@ public: } } - void Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize); + bool Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize); bool GetSaveRamPtr(int &size, uint8 *&data) { return mCart->GetSaveRamPtr(size, data); } // @@ -192,7 +192,7 @@ public: // Miscellaneous void SetButtonData(uint32 data) {mSusie->SetButtonData(data);}; - uint32 GetButtonData() {return mSusie->GetButtonData();}; + // uint32 GetButtonData() {return mSusie->GetButtonData();}; uint8* GetRamPointer() {return mRam->GetRamPointer();}; public: diff --git a/output/dll/bizlynx.dll b/output/dll/bizlynx.dll index 7554c99ebce3567a933c0335025f87c03cf75bad..d60ab6abceaf1886b185f209e546a3607fcbfd13 100644 GIT binary patch delta 7265 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 delta 7205 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