diff --git a/src/gui/game/DecorationTool.cpp b/src/gui/game/DecorationTool.cpp index d726e4afe..666a81397 100644 --- a/src/gui/game/DecorationTool.cpp +++ b/src/gui/game/DecorationTool.cpp @@ -1,9 +1,8 @@ #include "DecorationTool.h" - #include "graphics/Renderer.h" - #include "simulation/SimulationData.h" #include "simulation/Simulation.h" +#include "GameView.h" std::unique_ptr DecorationTool::GetIcon(int ToolID, Vec2 size) { @@ -54,6 +53,7 @@ void DecorationTool::DrawRect(Simulation * sim, Brush const &brush, ui::Point po void DecorationTool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) { + auto &rendererFrame = gameView->GetRendererFrame(); if (!rendererFrame.Size().OriginRect().Contains(position)) { return; diff --git a/src/gui/game/DecorationTool.h b/src/gui/game/DecorationTool.h index de61ca937..067100925 100644 --- a/src/gui/game/DecorationTool.h +++ b/src/gui/game/DecorationTool.h @@ -5,18 +5,19 @@ #include "graphics/RendererFrame.h" class Renderer; +class GameView; class DecorationTool: public Tool { public: RGBA Colour; - RendererFrame &rendererFrame; + GameView *gameView; std::unique_ptr GetIcon(int toolID, Vec2 size); - DecorationTool(RendererFrame &newRendererFrame, int decoMode, String name, String description, RGB colour, ByteString identifier): + DecorationTool(GameView *newGameView, int decoMode, String name, String description, RGB colour, ByteString identifier): Tool(decoMode, name, description, colour, identifier), Colour(0x000000_rgb .WithAlpha(0x00)), - rendererFrame(newRendererFrame) + gameView(newGameView) {} virtual ~DecorationTool() diff --git a/src/gui/game/GameModel.cpp b/src/gui/game/GameModel.cpp index 130dcfcb2..8648932c5 100644 --- a/src/gui/game/GameModel.cpp +++ b/src/gui/game/GameModel.cpp @@ -396,13 +396,13 @@ void GameModel::BuildMenus() menuList[SC_LIFE]->AddTool(new GOLTool(*this)); //Add decoration tools to menu - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_ADD, "ADD", "Colour blending: Add.", 0x000000_rgb, "DEFAULT_DECOR_ADD")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_SUBTRACT, "SUB", "Colour blending: Subtract.", 0x000000_rgb, "DEFAULT_DECOR_SUB")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_MULTIPLY, "MUL", "Colour blending: Multiply.", 0x000000_rgb, "DEFAULT_DECOR_MUL")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_DIVIDE, "DIV", "Colour blending: Divide." , 0x000000_rgb, "DEFAULT_DECOR_DIV")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_SMUDGE, "SMDG", "Smudge tool, blends surrounding deco together.", 0x000000_rgb, "DEFAULT_DECOR_SMDG")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_CLEAR, "CLR", "Erase any set decoration.", 0x000000_rgb, "DEFAULT_DECOR_CLR")); - menuList[SC_DECO]->AddTool(new DecorationTool(view->rendererFrame, DECO_DRAW, "SET", "Draw decoration (No blending).", 0x000000_rgb, "DEFAULT_DECOR_SET")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_ADD, "ADD", "Colour blending: Add.", 0x000000_rgb, "DEFAULT_DECOR_ADD")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_SUBTRACT, "SUB", "Colour blending: Subtract.", 0x000000_rgb, "DEFAULT_DECOR_SUB")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_MULTIPLY, "MUL", "Colour blending: Multiply.", 0x000000_rgb, "DEFAULT_DECOR_MUL")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_DIVIDE, "DIV", "Colour blending: Divide." , 0x000000_rgb, "DEFAULT_DECOR_DIV")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_SMUDGE, "SMDG", "Smudge tool, blends surrounding deco together.", 0x000000_rgb, "DEFAULT_DECOR_SMDG")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_CLEAR, "CLR", "Erase any set decoration.", 0x000000_rgb, "DEFAULT_DECOR_CLR")); + menuList[SC_DECO]->AddTool(new DecorationTool(view, DECO_DRAW, "SET", "Draw decoration (No blending).", 0x000000_rgb, "DEFAULT_DECOR_SET")); SetColourSelectorColour(colour); // update tool colors decoToolset[0] = GetToolFromIdentifier("DEFAULT_DECOR_SET"); decoToolset[1] = GetToolFromIdentifier("DEFAULT_DECOR_CLR"); diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index b25a77094..259f85985 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -734,6 +734,7 @@ void GameView::NotifyColourSelectorColourChanged(GameModel * sender) void GameView::NotifyRendererChanged(GameModel * sender) { ren = sender->GetRenderer(); + rendererFrame = &ren->GetVideo(); rendererSettings = &sender->GetRendererSettings(); } @@ -916,7 +917,7 @@ ByteString GameView::TakeScreenshot(int captureUI, int fileType) std::unique_ptr screenshot; if (captureUI) { - screenshot = std::make_unique(rendererFrame); + screenshot = std::make_unique(*rendererFrame); } else { @@ -2158,7 +2159,8 @@ void GameView::OnDraw() { StartRendererThread(); WaitForRendererThread(); - rendererFrame = ren->GetVideo(); + *rendererThreadResult = ren->GetVideo(); + rendererFrame = rendererThreadResult.get(); DispatchRendererThread(); } else @@ -2166,10 +2168,10 @@ void GameView::OnDraw() PauseRendererThread(); ren->ApplySettings(*rendererSettings); RenderSimulation(*sim, true); - rendererFrame = ren->GetVideo(); + rendererFrame = &ren->GetVideo(); } - std::copy_n(rendererFrame.data(), rendererFrame.Size().X * rendererFrame.Size().Y, g->Data()); + std::copy_n(rendererFrame->data(), rendererFrame->Size().X * rendererFrame->Size().Y, g->Data()); if (showBrush && selectMode == SelectNone && (!zoomEnabled || zoomCursorFixed) && activeBrush && (isMouseDown || (currentMouse.X >= 0 && currentMouse.X < XRES && currentMouse.Y >= 0 && currentMouse.Y < YRES))) { @@ -2284,7 +2286,7 @@ void GameView::OnDraw() if(recording) { - std::vector data = VideoBuffer(rendererFrame).ToPPM(); + std::vector data = VideoBuffer(*rendererFrame).ToPPM(); ByteString filename = ByteString::Build("recordings", PATH_SEP_CHAR, recordingFolder, PATH_SEP_CHAR, "frame_", Format::Width(recordingIndex++, 6), ".ppm"); @@ -2609,11 +2611,11 @@ std::optional GameView::FindingElementCandidate() const pixel GameView::GetPixelUnderMouse() const { auto point = c->PointTranslate(currentMouse); - if (!rendererFrame.Size().OriginRect().Contains(point)) + if (!rendererFrame->Size().OriginRect().Contains(point)) { return 0; } - return rendererFrame[point]; + return (*rendererFrame)[point]; } void GameView::RendererThread() @@ -2645,6 +2647,7 @@ void GameView::StartRendererThread() if (rendererThreadState == rendererThreadAbsent) { rendererThreadSim = std::make_unique(); + rendererThreadResult = std::make_unique(); rendererThreadState = rendererThreadRunning; start = true; } diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h index 3fe832a54..096ce3754 100644 --- a/src/gui/game/GameView.h +++ b/src/gui/game/GameView.h @@ -171,6 +171,8 @@ private: void WaitForRendererThread(); void DispatchRendererThread(); std::unique_ptr rendererThreadSim; + std::unique_ptr rendererThreadResult; + const RendererFrame *rendererFrame = nullptr; public: GameView(); @@ -261,7 +263,10 @@ public: void SkipIntroText(); pixel GetPixelUnderMouse() const; - RendererFrame rendererFrame; + const RendererFrame &GetRendererFrame() const + { + return *rendererFrame; + } // Call this before accessing Renderer "out of turn", e.g. from RenderView. This *does not* // include OptionsModel or Lua setting functions because they only access the RendererSettings // in GameModel, or Lua drawing functions because they only access Renderer in eventTraitSimGraphics diff --git a/src/lua/LuaSimulation.cpp b/src/lua/LuaSimulation.cpp index 7ab9fdaff..a90cab363 100644 --- a/src/lua/LuaSimulation.cpp +++ b/src/lua/LuaSimulation.cpp @@ -834,7 +834,7 @@ static int floodDeco(lua_State *L) auto *lsi = GetLSI(); // hilariously broken, intersects with console and all Lua graphics - auto &rendererFrame = lsi->gameModel->view->rendererFrame; + auto &rendererFrame = lsi->gameModel->view->GetRendererFrame(); auto loc = RGB::Unpack(rendererFrame[{ x, y }]); lsi->sim->ApplyDecorationFill(rendererFrame, x, y, r, g, b, a, loc.Red, loc.Green, loc.Blue); return 0;