From df6fa1dec05755127376e3424ca327b7a5d54c81 Mon Sep 17 00:00:00 2001 From: goyuken Date: Sat, 3 May 2014 03:05:34 +0000 Subject: [PATCH] gambatte: fix video problem related to new frame timing --- .../Consoles/Nintendo/Gameboy/Gambatte.cs | 7 +- .../Consoles/Nintendo/Gameboy/GambatteLink.cs | 6 +- .../Consoles/Nintendo/Gameboy/LibGambatte.cs | 68 ++++++------------ libgambatte/include/gambatte.h | 25 ++----- libgambatte/src/cinterface.cpp | 42 +++-------- libgambatte/src/cinterface.h | 5 +- libgambatte/src/gambatte.cpp | 56 ++++++++------- libgambatte/src/statesaver.cpp | 4 +- libgambatte/src/statesaver.h | 3 +- output/dll/libgambatte.dll | Bin 175104 -> 175616 bytes 10 files changed, 83 insertions(+), 133 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index 58d70a305f..810328def3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -235,7 +235,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { uint samplesEmitted = TICKSINFRAME - frameOverflow; // according to gambatte docs, this is the nominal length of a frame in 2mhz clocks System.Diagnostics.Debug.Assert(samplesEmitted * 2 <= soundbuff.Length); - LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref samplesEmitted); + if (LibGambatte.gambatte_runfor(GambatteState, soundbuff, ref samplesEmitted) > 0) + { + LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160); + } _cycleCount += (ulong)samplesEmitted; frameOverflow += samplesEmitted; @@ -431,7 +434,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy uint nlen = 0; IntPtr ndata = IntPtr.Zero; - if (!LibGambatte.gambatte_savestate(GambatteState, VideoBuffer, 160, ref ndata, ref nlen)) + if (!LibGambatte.gambatte_savestate(GambatteState, ref ndata, ref nlen)) throw new Exception("Gambatte failed to save the savestate!"); if (nlen == 0) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs index 1027f30636..460ba48429 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs @@ -151,13 +151,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy while (nL < target) { uint nsamp = (uint)(target - nL); - LibGambatte.gambatte_runfor(L.GambatteState, leftvbuff, pitch, leftsbuff + nL * 2, ref nsamp); + if (LibGambatte.gambatte_runfor(L.GambatteState, leftsbuff + nL * 2, ref nsamp) > 0) + LibGambatte.gambatte_blitto(L.GambatteState, leftvbuff, pitch); nL += (int)nsamp; } while (nR < target) { uint nsamp = (uint)(target - nR); - LibGambatte.gambatte_runfor(R.GambatteState, rightvbuff, pitch, rightsbuff + nR * 2, ref nsamp); + if (LibGambatte.gambatte_runfor(R.GambatteState, rightsbuff + nR * 2, ref nsamp) > 0) + LibGambatte.gambatte_blitto(R.GambatteState, rightvbuff, pitch); nR += (int)nsamp; } // poll link cable statuses diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs index cffd2462b4..d4a57ed26b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs @@ -30,7 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// Use GBA intial CPU register values when in CGB mode. GBA_CGB = 2, /// Use heuristics to detect and support some multicart MBCs disguised as MBC1. - MULTICART_COMPAT = 4 + MULTICART_COMPAT = 4 } /// @@ -60,15 +60,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// exact time (in number of samples) at which it was drawn. /// /// opaque state pointer - /// 160x144 RGB32 (native endian) video frame buffer or null - /// distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. /// buffer with space >= samples + 2064 /// in: number of stereo samples to produce, out: actual number of samples produced /// sample number at which the video frame was produced. -1 means no frame was produced. [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int gambatte_runfor(IntPtr core, int[] videobuf, int pitch, short[] soundbuf, ref uint samples); + public static extern int gambatte_runfor(IntPtr core, 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); + unsafe public static extern int gambatte_runfor(IntPtr core, short* soundbuf, ref uint samples); + + /// + /// blit from internal framebuffer to provided framebuffer + /// + /// opaque state pointer + /// + /// in pixels + [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] + unsafe public static extern void gambatte_blitto(IntPtr core, int* videobuf, int pitch); + /// + /// blit from internal framebuffer to provided framebuffer + /// + /// opaque state pointer + /// + /// in pixels + [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gambatte_blitto(IntPtr core, int[] videobuf, int pitch); /// /// Reset to initial state. @@ -112,7 +127,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// [Flags] public enum Buttons - { + { A = 0x01, B = 0x02, SELECT = 0x04, @@ -268,13 +283,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// Saves emulator state to a byte array /// /// opaque state pointer - /// 160x144 RGB32 (native endian) video frame buffer or 0. Used for saving a thumbnail. NOT USED ANYMORE - /// distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. /// private savestate data returned by the core /// the length of the data in bytes /// success [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool gambatte_savestate(IntPtr core, int[] videobuf, int pitch, ref IntPtr data, ref uint len); + public static extern bool gambatte_savestate(IntPtr core, ref IntPtr data, ref uint len); /// /// destroy data returned by gambatte_savestate() to avoid memory leaks @@ -293,43 +306,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] public static extern bool gambatte_loadstate(IntPtr core, byte[] data, uint len); - /// - /// Saves emulator state to the file given by 'filepath'. - /// - /// opaque state pointer - /// 160x144 RGB32 (native endian) video frame buffer or 0. Used for saving a thumbnail. - /// distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. - /// - /// success - //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - //public static extern bool gambatte_savestate_file(IntPtr core, int[] videobuf, int pitch, string filepath); - - /// - /// Loads emulator state from the file given by 'filepath'. - /// - /// opaque state pointer - /// - /// success - //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - //public static extern bool gambatte_loadstate_file(IntPtr core, string filepath); - - /// - /// Selects which state slot to save state to or load state from. - /// There are 10 such slots, numbered from 0 to 9 (periodically extended for all n). - /// - /// opaque state pointer - /// - //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - //public static extern void gambatte_selectstate(IntPtr core, int n); - - /// - /// Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive. - /// - /// opaque state pointer - /// - //[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - //public static extern int gambatte_currentstate(IntPtr core); - /// /// ROM header title of currently loaded ROM image. /// diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index 51868a5b2e..2e4a65dd2b 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -62,15 +62,14 @@ public: * The return value indicates whether a new video frame has been drawn, and the * exact time (in number of samples) at which it was drawn. * - * @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0 - * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. * @param soundBuf buffer with space >= samples + 2064 * @param samples in: number of stereo samples to produce, out: actual number of samples produced * @return sample number at which the video frame was produced. -1 means no frame was produced. */ - long runFor(gambatte::uint_least32_t *videoBuf, int pitch, - gambatte::uint_least32_t *soundBuf, unsigned &samples); - + long runFor(gambatte::uint_least32_t *soundBuf, unsigned &samples); + + void blitTo(gambatte::uint_least32_t *videoBuf, int pitch); + /** Reset to initial state. * Equivalent to reloading a ROM image, or turning a Game Boy Color off and on again. */ @@ -109,20 +108,6 @@ public: // 0 = vram, 1 = rom, 2 = wram, 3 = cartram, 4 = oam, 5 = hram bool getMemoryArea(int which, unsigned char **data, int *length); - - /** Saves emulator state to the state slot selected with selectState(). - * The data will be stored in the directory given by setSaveDir(). - * - * @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0. Used for saving a thumbnail. - * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. - * @return success - */ - //bool saveState(const gambatte::uint_least32_t *videoBuf, int pitch); - - /** Loads emulator state from the state slot selected with selectState(). - * @return success - */ - //bool loadState(); /** Saves emulator state to the file given by 'filepath'. * @@ -130,7 +115,7 @@ public: * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. * @return success */ - bool saveState(const gambatte::uint_least32_t *videoBuf, int pitch, std::ostream &file); + bool saveState(std::ostream &file); /** Loads emulator state from the file given by 'filepath'. * @return success diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp index 4e72a1f7c8..242dda2aef 100644 --- a/libgambatte/src/cinterface.cpp +++ b/libgambatte/src/cinterface.cpp @@ -24,15 +24,21 @@ __declspec(dllexport) int gambatte_load(void *core, const char *romfiledata, uns return ret; } -__declspec(dllexport) long gambatte_runfor(void *core, unsigned long *videobuf, int pitch, short *soundbuf, unsigned *samples) +__declspec(dllexport) long gambatte_runfor(void *core, short *soundbuf, unsigned *samples) { GB *g = (GB *) core; unsigned sampv = *samples; - long ret = g->runFor((unsigned int*)videobuf, pitch, (unsigned int *) soundbuf, sampv); + long ret = g->runFor((unsigned int *) soundbuf, sampv); *samples = sampv; return ret; } +__declspec(dllexport) void gambatte_blitto(void *core, unsigned long *videobuf, int pitch) +{ + GB *g = (GB *) core; + g->blitTo((unsigned int *)videobuf, pitch); +} + __declspec(dllexport) void gambatte_reset(void *core, long long now) { GB *g = (GB *) core; @@ -151,26 +157,12 @@ __declspec(dllexport) int gambatte_savesavedatalength(void *core) return g->saveSavedataLength(); } -/* -__declspec(dllexport) int gambatte_savestate(void *core, const unsigned long *videobuf, int pitch) -{ - GB *g = (GB *) core; - return g->saveState(videobuf, pitch); -} - -__declspec(dllexport) int gambatte_loadstate(void *core) -{ - GB *g = (GB *) core; - return g->loadState(); -} -*/ - -__declspec(dllexport) int gambatte_savestate(void *core, const unsigned long *videobuf, int pitch, char **data, unsigned *len) +__declspec(dllexport) int gambatte_savestate(void *core, char **data, unsigned *len) { GB *g = (GB *) core; std::ostringstream os = std::ostringstream(std::ios_base::binary | std::ios_base::out); - if (!g->saveState((const unsigned int*)videobuf, pitch, os)) + if (!g->saveState(os)) return 0; os.flush(); @@ -193,20 +185,6 @@ __declspec(dllexport) int gambatte_loadstate(void *core, const char *data, unsig return g->loadState(std::istringstream(std::string(data, len), std::ios_base::binary | std::ios_base::in)); } -/* -__declspec(dllexport) void gambatte_selectstate(void *core, int n) -{ - GB *g = (GB *) core; - g->selectState(n); -} - -__declspec(dllexport) int gambatte_currentstate(void *core) -{ - GB *g = (GB *) core; - return g->currentState(); -} -*/ - static char horriblebuff[64]; __declspec(dllexport) const char *gambatte_romtitle(void *core) { diff --git a/libgambatte/src/cinterface.h b/libgambatte/src/cinterface.h index 3f0bae5056..57cc1e16f2 100644 --- a/libgambatte/src/cinterface.h +++ b/libgambatte/src/cinterface.h @@ -10,7 +10,8 @@ extern "C" __declspec(dllexport) int gambatte_load(void *core, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags); - __declspec(dllexport) long gambatte_runfor(void *core, unsigned long *videobuf, int pitch, short *soundbuf, unsigned *samples); + __declspec(dllexport) long gambatte_runfor(void *core, short *soundbuf, unsigned *samples); + __declspec(dllexport) void gambatte_blitto(void *core, unsigned long *videobuf, int pitch); __declspec(dllexport) void gambatte_reset(void *core, long long now); @@ -46,7 +47,7 @@ extern "C" //__declspec(dllexport) int gambatte_loadstate(void *core); - __declspec(dllexport) int gambatte_savestate(void *core, const unsigned long *videobuf, int pitch, char **data, unsigned *len); + __declspec(dllexport) int gambatte_savestate(void *core, char **data, unsigned *len); __declspec(dllexport) void gambatte_savestate_destroy(char *data); __declspec(dllexport) int gambatte_loadstate(void *core, const char *data, unsigned len); diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp index 5676ac2c8f..89a00dbfe1 100644 --- a/libgambatte/src/gambatte.cpp +++ b/libgambatte/src/gambatte.cpp @@ -39,8 +39,18 @@ struct GB::Priv { CPU cpu; int stateNo; bool gbaCgbMode; + + gambatte::uint_least32_t *vbuff; - Priv() : stateNo(1), gbaCgbMode(false) {} + Priv() : stateNo(1), gbaCgbMode(false) + { + vbuff = new gambatte::uint_least32_t[160*144]; + } + + ~Priv() + { + delete[] vbuff; + } }; GB::GB() : p_(new Priv) {} @@ -52,14 +62,13 @@ GB::~GB() { delete p_; } -long GB::runFor(gambatte::uint_least32_t *const videoBuf, const int pitch, - gambatte::uint_least32_t *const soundBuf, unsigned &samples) { +long GB::runFor(gambatte::uint_least32_t *const soundBuf, unsigned &samples) { if (!p_->cpu.loaded()) { samples = 0; return -1; } - p_->cpu.setVideoBuffer(videoBuf, pitch); + p_->cpu.setVideoBuffer(p_->vbuff, 160); p_->cpu.setSoundBuffer(soundBuf); const long cyclesSinceBlit = p_->cpu.runFor(samples * 2); samples = p_->cpu.fillSoundBuffer(); @@ -67,6 +76,19 @@ long GB::runFor(gambatte::uint_least32_t *const videoBuf, const int pitch, return cyclesSinceBlit < 0 ? cyclesSinceBlit : static_cast(samples) - (cyclesSinceBlit >> 1); } +void GB::blitTo(gambatte::uint_least32_t *videoBuf, int pitch) +{ + gambatte::uint_least32_t *src = p_->vbuff; + gambatte::uint_least32_t *dst = videoBuf; + + for (int i = 0; i < 144; i++) + { + std::memcpy(dst, src, sizeof(gambatte::uint_least32_t) * 160); + src += 160; + dst += pitch; + } +} + void GB::reset(const std::uint32_t now) { if (p_->cpu.loaded()) { @@ -201,37 +223,23 @@ bool GB::loadState(std::istream &file) { if (StateSaver::loadState(state, file)) { p_->cpu.loadState(state); + file.read((char *)p_->vbuff, 160 * 144 * 4); // yes, sloppy return true; } } return false; } -/* -bool GB::saveState(const gambatte::uint_least32_t *const videoBuf, const int pitch) { - if (saveState(videoBuf, pitch, statePath(p_->cpu.saveBasePath(), p_->stateNo))) { - p_->cpu.setOsdElement(newStateSavedOsdElement(p_->stateNo)); - return true; - } - return false; -} - -bool GB::loadState() { - if (loadState(statePath(p_->cpu.saveBasePath(), p_->stateNo))) { - p_->cpu.setOsdElement(newStateLoadedOsdElement(p_->stateNo)); - return true; - } - - return false; -} -*/ -bool GB::saveState(const gambatte::uint_least32_t *const videoBuf, const int pitch, std::ostream &file) { +bool GB::saveState(std::ostream &file) { if (p_->cpu.loaded()) { SaveState state; p_->cpu.setStatePtrs(state); p_->cpu.saveState(state); - return StateSaver::saveState(state, videoBuf, pitch, file); + bool ret = StateSaver::saveState(state, file); + if (ret) + file.write((const char *)p_->vbuff, 160 * 144 * 4); // yes, sloppy + return ret; } return false; diff --git a/libgambatte/src/statesaver.cpp b/libgambatte/src/statesaver.cpp index 1640b82428..d8c3131a13 100644 --- a/libgambatte/src/statesaver.cpp +++ b/libgambatte/src/statesaver.cpp @@ -410,9 +410,7 @@ static SaverList list; namespace gambatte { -bool StateSaver::saveState(const SaveState &state, - const uint_least32_t *const videoBuf, - const int pitch, std::ostream &file) { +bool StateSaver::saveState(const SaveState &state, std::ostream &file) { //std::ostream file(filename.c_str(), std::ios_base::binary); if (file.fail()) diff --git a/libgambatte/src/statesaver.h b/libgambatte/src/statesaver.h index dec12fc998..46f2817603 100644 --- a/libgambatte/src/statesaver.h +++ b/libgambatte/src/statesaver.h @@ -35,8 +35,7 @@ public: enum { SS_WIDTH = 160 >> SS_SHIFT }; enum { SS_HEIGHT = 144 >> SS_SHIFT }; - static bool saveState(const SaveState &state, - const uint_least32_t *videoBuf, int pitch, std::ostream &file); + static bool saveState(const SaveState &state, std::ostream &file); static bool loadState(SaveState &state, std::istream &file); }; diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll index 9b974c9fd82474eeb3615672dfcf38359e34f305..2f5e11e7ed2ceb9d55cafe9db6221328d9073c21 100644 GIT binary patch delta 19868 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 u)G2jZT~}RS-4I>8ZnAE+F3