diff --git a/src/common/Bezel.cxx b/src/common/Bezel.cxx index 7a12e54d8..850e57024 100644 --- a/src/common/Bezel.cxx +++ b/src/common/Bezel.cxx @@ -63,19 +63,6 @@ const string Bezel::getName(int& index) const return ""; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Bezel::checkPixel(uInt32 x, uInt32 y) const -{ - uInt32 *pixels{nullptr}, pitch; - uInt8 r, g, b, a; - - mySurface->basePtr(pixels, pitch); - pixels += x + y * pitch; - myFB.getRGBA(*pixels, &r, &g, &b, &a); - - return a != 0; // pixel is not fully transparent -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Bezel::borderSize(uInt32 x, uInt32 y, uInt32 size, Int32 step) const { @@ -102,17 +89,15 @@ bool Bezel::load() bool isValid = false; #ifdef IMAGE_SUPPORT - const bool isShown = myOSystem.eventHandler().inTIAMode() && - myOSystem.settings().getBool("bezel.show") && - (myFB.fullScreen() || myOSystem.settings().getBool("bezel.windowed")); + const bool show = myOSystem.eventHandler().inTIAMode() && + myOSystem.settings().getBool("bezel.show") && + (myOSystem.settings().getBool("fullscreen") || + myOSystem.settings().getBool("bezel.windowed")); - if(mySurface) - myFB.deallocateSurface(mySurface); - mySurface = nullptr; - - if(isShown) + if(show) { - mySurface = myFB.allocateSurface(1, 1); // dummy size + if(!mySurface) + mySurface = myFB.allocateSurface(1, 1); // dummy size try { const string& path = myOSystem.bezelDir().getPath(); @@ -149,7 +134,6 @@ bool Bezel::load() const Int32 w = mySurface->width(); const Int32 h = mySurface->height(); uInt32 top, bottom, left, right; - bool isRounded; if(settings.getBool("bezel.win.auto")) { @@ -162,12 +146,6 @@ bool Bezel::load() yCenter = (bottom + top) >> 1; left = borderSize(0, yCenter, w, 1); right = w - 1 - borderSize(w - 1, yCenter, w, -1); - - // Check if pixels close to the borders are not fully transparent - isRounded = checkPixel(left + w / 100, top + h / 100) - || checkPixel(right - w / 100, top + h / 100) - || checkPixel(left + w / 100, bottom - h / 100) - || checkPixel(right - w / 100, bottom - h / 100); } else { @@ -179,15 +157,14 @@ bool Bezel::load() right = w - 1 - std::min(w - 1, static_cast(w * settings.getInt("bezel.win.right") / 100. + .5)); top = std::min(h - 1, static_cast(h * settings.getInt("bezel.win.top") / 100. + .5)); bottom = h - 1 - std::min(h - 1, static_cast(h * settings.getInt("bezel.win.bottom") / 100. + .5)); - isRounded = settings.getBool("bezel.win.rounded"); } //cerr << (int)(right - left + 1) << " x " << (int)(bottom - top + 1) << " = " - // << double((int)(right - left + 1)) / double((int)(bottom - top + 1)) << endl; + // << double((int)(right - left + 1)) / double((int)(bottom - top + 1)); // Disable bezel is no transparent window was found if (left < right && top < bottom) - myInfo = Info(Common::Size(w, h), Common::Rect(left, top, right + 1, bottom + 1), isRounded); + myInfo = Info(Common::Size(w, h), Common::Rect(left, top, right, bottom)); else myInfo = Info(); } @@ -209,11 +186,6 @@ void Bezel::apply() std::min(myFB.screenSize().h, static_cast(std::round(myFB.imageRect().h() * myInfo.ratioH()))); - //cerr << myInfo.ratioW() << ", " << myInfo.ratioH() << endl; - //cerr << myInfo.size() << "; " << myInfo.window() << endl; - //cerr << myFB.imageRect().size() << "; " << std::round(imageW * myInfo.ratioW()) << endl; - //cerr << "dbl: " << bezelW << " x " << bezelH << endl; - // Position and scale bezel mySurface->setDstSize(bezelW, bezelH); mySurface->setDstPos((myFB.screenSize().w - bezelW) / 2, // center @@ -227,12 +199,14 @@ void Bezel::apply() mySurface->applyAttributes(); mySurface->setVisible(true); } + else + if(mySurface) + mySurface->setVisible(false); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Bezel::render(bool force) +void Bezel::render() { - // Only bezels with rounded windows have to be rendered each frame - if(mySurface && (myInfo.isRounded() || force)) + if(mySurface) mySurface->render(); } diff --git a/src/common/Bezel.hxx b/src/common/Bezel.hxx index 28b00ee5e..8bdeec952 100644 --- a/src/common/Bezel.hxx +++ b/src/common/Bezel.hxx @@ -65,17 +65,15 @@ class Bezel bool _isShown{false}; // Is bezel shown? Common::Size _size{1, 1}; // Bezel size Common::Rect _window{1, 1}; // Area of transparent TIA window inside bezel - bool _isRounded{false}; // true, if the bezel window has rounded corners public: explicit Info() = default; - explicit Info(const Common::Size& size, const Common::Rect& window, bool isRounded) - : _isShown{true}, _size{size}, _window{window}, _isRounded{isRounded} { } + explicit Info(Common::Size size, Common::Rect window) + : _isShown{true}, _size{size}, _window{window} { } bool isShown() const { return _isShown; } - const Common::Size& size() const { return _size; } - const Common::Rect& window() const { return _window; } - bool isRounded() const { return _isRounded; } + Common::Size size() const { return _size; } + Common::Rect window() const { return _window; } // Ratios between bezel sizes and TIA window sizes double ratioW() const { return static_cast(size().w) / window().w(); } @@ -85,20 +83,12 @@ class Bezel // Structure access methods const Info& info() const { return myInfo; } bool isShown() const { return myInfo.isShown(); } - const Common::Size& size() const { return myInfo.size(); } - const Common::Rect& window() const { return myInfo.window(); } - bool isRounded() const { return myInfo.isRounded(); } + Common::Size size() const { return myInfo.size(); } + Common::Rect window() const { return myInfo.window(); } // Ratio between bezel size and TIA window size double ratioW() const { return myInfo.ratioW(); } double ratioH() const { return myInfo.ratioH(); } - /* - Check if a pixel is not fully transparent. - - @return true, if pixel is not fully transparent - */ - bool checkPixel(uInt32 x, uInt32 y) const; - /* Calculate size of a bezel border. */ @@ -117,7 +107,7 @@ class Bezel /* Render bezel surface */ - void render(bool force); + void render(); private: /* diff --git a/src/common/VideoModeHandler.cxx b/src/common/VideoModeHandler.cxx index c9a518df2..d220dcb18 100644 --- a/src/common/VideoModeHandler.cxx +++ b/src/common/VideoModeHandler.cxx @@ -63,8 +63,6 @@ const VideoModeHandler::Mode& // First calculate maximum zoom that keeps aspect ratio const double scaleX = static_cast(myImage.w) / (myDisplay.w / bezelInfo.ratioW()), scaleY = static_cast(myImage.h) / (myDisplay.h / bezelInfo.ratioH()); - // Note: Since the scale value may differ, the bezel may not be scaled to fully size. - // One value might be tiny bit smaller. double zoom = 1. / std::max(scaleX, scaleY); // When aspect ratio correction is off, we want pixel-exact images, @@ -116,7 +114,7 @@ VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, : screenS{sw, sh}, stretch{smode}, description{desc}, - zoom{zoomLevel}, + zoom{zoomLevel}, //hZoom{zoomLevel}, vZoom{zoomLevel}, fsIndex{fsindex} { // Now resize based on windowed/fullscreen mode and stretch factor diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index e5f27b2bd..4017e2ef7 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -281,7 +281,7 @@ FBInitStatus FrameBuffer::createDisplay(string_view title, BufferType type, if(myBufferType == BufferType::Emulator) { - myBezel->load(); +// myBezel->load(); // Determine possible TIA windowed zoom levels const double currentTIAZoom = @@ -588,7 +588,7 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond) // We don't worry about selective rendering here; the rendering // always happens at the full framerate - renderTIA(false); // do not clear screen in emulation mode + renderTIA(); // Show frame statistics if(myStatsMsg.enabled) @@ -967,7 +967,7 @@ void FrameBuffer::renderTIA(bool doClear, bool shade) myTIASurface->render(shade); if(myBezel) - myBezel->render(doClear); // force rendering if framebuffer was cleared + myBezel->render(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1309,11 +1309,6 @@ FBInitStatus FrameBuffer::applyVideoMode() const Settings& s = myOSystem.settings(); const int display = displayId(); - // Get rid of the previous output - myBackend->clear(); - myBackend->renderToScreen(); - myBackend->clear(); - if(s.getBool("fullscreen")) myVidModeHandler.setDisplaySize(myFullscreenDisplays[display], display); else @@ -1321,6 +1316,11 @@ FBInitStatus FrameBuffer::applyVideoMode() const bool inTIAMode = myOSystem.eventHandler().inTIAMode(); +#ifdef IMAGE_SUPPORT + if(inTIAMode) + myBezel->load(); +#endif + // Build the new mode based on current settings const VideoModeHandler::Mode& mode = myVidModeHandler.buildMode(s, inTIAMode, myBezel->info()); @@ -1347,23 +1347,14 @@ FBInitStatus FrameBuffer::applyVideoMode() // Inform TIA surface about new mode, and update TIA settings if(inTIAMode) { -#ifdef IMAGE_SUPPORT - myBezel->apply(); - if(!myBezel->info().isRounded()) - { - // If the bezel window is not rounded, it has to be rendered only once for each buffer - myBezel->render(true); - myBackend->renderToScreen(); - myBezel->render(true); - } -#endif - - myTIASurface->initialize(myOSystem.console(), myActiveVidMode); + myTIASurface->initialize(myOSystem.console(), myActiveVidMode); if(fullScreen()) myOSystem.settings().setValue("tia.fs_stretch", myActiveVidMode.stretch == VideoModeHandler::Mode::Stretch::Fill); else myOSystem.settings().setValue("tia.zoom", myActiveVidMode.zoom); + + myBezel->apply(); } resetSurfaces(); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 3d61b48e6..3eff1c00f 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -69,7 +69,6 @@ Settings::Settings() setPermanent("bezel.win.right", "12"); setPermanent("bezel.win.top", "0"); setPermanent("bezel.win.bottom", "0"); - setPermanent("bezel.win.rounded", "false"); // TIA specific options setPermanent("tia.inter", "false"); setPermanent("tia.zoom", "3"); @@ -548,14 +547,13 @@ void Settings::usage() << " -uimessages <1|0> Show onscreen UI messages for different events\n" << " -pausedim <1|0> Enable emulation dimming in pause mode\n" << endl - << " -bezel.show <1|0> Show bezel around emulation window\n" - << " -bezel.windowed <1|0> Show bezel in windowed modes\n" - << " -bezel.win.auto <1|0> Automatically set bezel window position\n" - << " -bezel.win.left <0-40> Set left bezel window position [%]\n" - << " -bezel.win.right <0-40> Set right bezel window position [%]\n" - << " -bezel.win.top <0-40> Set top bezel window position [%]\n" - << " -bezel.win.bottom <0-40> Set bottom bezel window position [%]\n" - << " -bezel.win.rounded <1|0> Set if the bezel window has rounded borders\n" + << " -bezel.show <1|0> Show bezel around emulation window\n" + << " -bezel.windowed <1|0> Show bezel in windowed modes\n" + << " -bezel.win.auto <1|0> Automatically set bezel window position\n" + << " -bezel.win.left <0-40> Set left bezel window position [%]\n" + << " -bezel.win.right <0-40> Set right bezel window position [%]\n" + << " -bezel.win.top <0-40> Set top bezel window position [%]\n" + << " -bezel.win.bottom <0-40> Set bottom bezel window position [%]\n" << endl #ifdef SOUND_SUPPORT << " -audio.enabled <1|0> Enable audio\n" diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index d6a36fb1f..781af548f 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -519,15 +519,7 @@ void VideoAudioDialog::addBezelTab() myWinBottomSlider->setTickmarkIntervals(4); wid.push_back(myWinBottomSlider); - // Mark bezel windows as rounded (requires rendering each frame) - ypos += lineHeight + VGAP; - myBezelWinRounded = new CheckboxWidget(myTab, _font, xpos, ypos, - "Rounded borders"); - myBezelWinRounded->setToolTip("Enable if the bezel window has rounded borders"); - wid.push_back(myBezelWinRounded); - // Add items for tab 3 - addToFocusList(wid, myTab, tabID); myTab->parentWidget(tabID)->setHelpAnchor("VideoAudioBezels"); } @@ -782,7 +774,6 @@ void VideoAudioDialog::loadConfig() myWinRightSlider->setValue(settings.getInt("bezel.win.right")); myWinTopSlider->setValue(settings.getInt("bezel.win.top")); myWinBottomSlider->setValue(settings.getInt("bezel.win.bottom")); - myBezelWinRounded->setState(settings.getBool("bezel.win.rounded")); handleBezelChange(); ///////////////////////////////////////////////////////////////////////////// @@ -918,7 +909,6 @@ void VideoAudioDialog::saveConfig() settings.setValue("bezel.win.right", myWinRightSlider->getValueLabel()); settings.setValue("bezel.win.top", myWinTopSlider->getValueLabel()); settings.setValue("bezel.win.bottom", myWinBottomSlider->getValueLabel()); - settings.setValue("bezel.win.rounded", myBezelWinRounded->getState()); // Note: The following has to happen after all video related setting have been saved if(instance().hasConsole()) @@ -1237,7 +1227,6 @@ void VideoAudioDialog::handleBezelChange() myWinRightSlider->setEnabled(enable && nonAuto); myWinTopSlider->setEnabled(enable && nonAuto); myWinBottomSlider->setEnabled(enable && nonAuto); - myBezelWinRounded->setEnabled(enable && nonAuto); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 85a588d8a..fe165619b 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -140,7 +140,6 @@ class VideoAudioDialog : public Dialog SliderWidget* myWinRightSlider{nullptr}; SliderWidget* myWinTopSlider{nullptr}; SliderWidget* myWinBottomSlider{nullptr}; - CheckboxWidget* myBezelWinRounded{nullptr}; // Audio CheckboxWidget* mySoundEnableCheckbox{nullptr};