diff --git a/include/fast/Fast3dWindow.h b/include/fast/Fast3dWindow.h index aa0795fb7..6b2f603f3 100644 --- a/include/fast/Fast3dWindow.h +++ b/include/fast/Fast3dWindow.h @@ -16,6 +16,7 @@ class Fast3dWindow : public Ship::Window { void Init() override; void Close() override; + void RunGuiOnly() override; void StartFrame() override; void EndFrame() override; bool IsFrameReady() override; diff --git a/include/fast/interpreter.h b/include/fast/interpreter.h index 5b5bf0e94..ee526729c 100644 --- a/include/fast/interpreter.h +++ b/include/fast/interpreter.h @@ -363,6 +363,7 @@ class Interpreter { void GetDimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY); GfxRenderingAPI* GetCurrentRenderingAPI(); void StartFrame(); + void RunGuiOnly(); void Run(Gfx* commands, const std::unordered_map& mtx_replacements); void EndFrame(); void HandleWindowEvents(); diff --git a/include/ship/window/Window.h b/include/ship/window/Window.h index 389e38cd3..b7dca53e5 100644 --- a/include/ship/window/Window.h +++ b/include/ship/window/Window.h @@ -35,6 +35,7 @@ class Window { virtual void Init() = 0; virtual void Close() = 0; + virtual void RunGuiOnly() = 0; virtual void StartFrame() = 0; virtual void EndFrame() = 0; virtual bool IsFrameReady() = 0; diff --git a/src/fast/Fast3dWindow.cpp b/src/fast/Fast3dWindow.cpp index 0db43533a..9943170d5 100644 --- a/src/fast/Fast3dWindow.cpp +++ b/src/fast/Fast3dWindow.cpp @@ -166,6 +166,10 @@ void Fast3dWindow::Close() { mWindowManagerApi->Close(); } +void Fast3dWindow::RunGuiOnly() { + mInterpreter->RunGuiOnly(); +} + void Fast3dWindow::StartFrame() { mInterpreter->StartFrame(); } diff --git a/src/fast/interpreter.cpp b/src/fast/interpreter.cpp index 98d92f5e4..d703b384b 100644 --- a/src/fast/interpreter.cpp +++ b/src/fast/interpreter.cpp @@ -4301,6 +4301,46 @@ void Interpreter::StartFrame() { GfxExecStack g_exec_stack = {}; +void Interpreter::RunGuiOnly() { + SpReset(); + + mGetPixelDepthPending.clear(); + mGetPixelDepthCached.clear(); + + mRapi->UpdateFramebufferParameters(0, mGfxCurrentWindowDimensions.width, mGfxCurrentWindowDimensions.height, 1, + false, true, true, !mRendersToFb); + mRapi->StartFrame(); + mRapi->StartDrawToFramebuffer(mRendersToFb ? mGameFb : 0, (float)mCurDimensions.height / mNativeDimensions.height); + mRapi->ClearFramebuffer(false, true); + mRdp->viewport_or_scissor_changed = true; + mRenderingState.viewport = {}; + mRenderingState.scissor = {}; + + Flush(); + mGfxFrameBuffer = 0; + + if (mRendersToFb) { + mRapi->StartDrawToFramebuffer(0, 1); + mRapi->ClearFramebuffer(true, true); + if (mMsaaLevel > 1) { + if (!ViewportMatchesRendererResolution()) { + mRapi->ResolveMSAAColorBuffer(mGameFbMsaaResolved, mGameFb); + mGfxFrameBuffer = (uintptr_t)mRapi->GetFramebufferTextureId(mGameFbMsaaResolved); + } else { + mRapi->ResolveMSAAColorBuffer(0, mGameFb); + } + } else { + mGfxFrameBuffer = (uintptr_t)mRapi->GetFramebufferTextureId(mGameFb); + } + } else if (mFbActive) { + // Failsafe reset to main framebuffer to prevent softlocking the renderer + mFbActive = 0; + mRapi->StartDrawToFramebuffer(0, 1); + + assert(0 && "active framebuffer was never reset back to original"); + } +} + void Interpreter::Run(Gfx* commands, const std::unordered_map& mtx_replacements) { SpReset();