From b8cd71d75aef9efab56f5b066dde3c3035403288 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 13 May 2020 09:32:11 +0200 Subject: [PATCH] added UI messages with gauge bars for variable values (partially addresses #631) --- src/common/PaletteHandler.cxx | 19 ++-- src/common/SoundSDL2.cxx | 12 +-- src/common/tv_filters/NTSCFilter.cxx | 34 ++----- src/common/tv_filters/NTSCFilter.hxx | 3 +- src/emucore/Console.cxx | 109 ++++++---------------- src/emucore/Console.hxx | 16 ++-- src/emucore/EventHandler.cxx | 38 ++++---- src/emucore/FrameBuffer.cxx | 130 ++++++++++++++++++++++----- src/emucore/FrameBuffer.hxx | 29 ++++-- src/emucore/TIASurface.cxx | 14 +-- src/gui/CommandDialog.cxx | 2 +- src/gui/MinUICommandDialog.cxx | 2 +- 12 files changed, 211 insertions(+), 197 deletions(-) diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index 70867d116..b0e4eea2d 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -144,11 +144,10 @@ void PaletteHandler::changeAdjustable(bool increase) *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal); - ostringstream buf; - buf << "Custom '" << myAdjustables[myCurrentAdjustable].name - << "' set to " << newVal << "%"; - - myOSystem.frameBuffer().showMessage(buf.str()); + ostringstream msg, val; + msg << "Palette " << myAdjustables[myCurrentAdjustable].name; + val << newVal << "%"; + myOSystem.frameBuffer().showMessage(msg.str(), val.str(), newVal); setPalette(); } } @@ -179,11 +178,11 @@ void PaletteHandler::changeColorPhaseShift(bool increase) generateCustomPalette(timing); setPalette(SETTING_CUSTOM); - ostringstream ss; - ss << "Color phase shift at " - << std::fixed << std::setprecision(1) << newPhase << DEGREE; - - myOSystem.frameBuffer().showMessage(ss.str()); + ostringstream val; + val << std::fixed << std::setprecision(1) << newPhase << DEGREE; + myOSystem.frameBuffer().showMessage("Palette phase shift", val.str(), newPhase, + (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_SHIFT, + (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_SHIFT); } } diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 671e5f83c..c32189e95 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -217,7 +217,6 @@ void SoundSDL2::setVolume(uInt32 percent) void SoundSDL2::adjustVolume(Int8 direction) { ostringstream strval; - string message; Int32 percent = myVolume; @@ -225,9 +224,7 @@ void SoundSDL2::adjustVolume(Int8 direction) percent -= 2; else if(direction == 1) percent += 2; - - if((percent < 0) || (percent > 100)) - return; + percent = BSPF::clamp(percent, 0, 100); setVolume(percent); @@ -241,11 +238,8 @@ void SoundSDL2::adjustVolume(Int8 direction) } // Now show an onscreen message - strval << percent; - message = "Volume set to "; - message += strval.str(); - - myOSystem.frameBuffer().showMessage(message); + strval << percent << "%"; + myOSystem.frameBuffer().showMessage("Volume", strval.str(), percent); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/tv_filters/NTSCFilter.cxx b/src/common/tv_filters/NTSCFilter.cxx index 5a275fbf2..d742cc674 100644 --- a/src/common/tv_filters/NTSCFilter.cxx +++ b/src/common/tv_filters/NTSCFilter.cxx @@ -112,40 +112,24 @@ string NTSCFilter::setPreviousAdjustable() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string NTSCFilter::increaseAdjustable() +void NTSCFilter::changeAdjustable(bool increase, string& text, string& valueText, Int32& value) { //if(myPreset != Preset::CUSTOM) // return "'Custom' TV mode not selected"; - uInt32 newval = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value); - newval += 2; if(newval > 100) newval = 100; - *ourCustomAdjustables[myCurrentAdjustable].value = scaleFrom100(newval); + value = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value); + value = BSPF::clamp(value + (increase ? 2 : -2), 0, 100); - ostringstream buf; - buf << "Custom '" << ourCustomAdjustables[myCurrentAdjustable].type - << "' set to " << newval << "%"; + *ourCustomAdjustables[myCurrentAdjustable].value = scaleFrom100(value); setPreset(myPreset); - return buf.str(); -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string NTSCFilter::decreaseAdjustable() -{ - //if(myPreset != Preset::CUSTOM) - // return "'Custom' TV mode not selected"; + ostringstream msg, val; + msg << "Custom " << ourCustomAdjustables[myCurrentAdjustable].type; + val << value << "%"; - uInt32 newval = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value); - if(newval < 2) newval = 0; - else newval -= 2; - *ourCustomAdjustables[myCurrentAdjustable].value = scaleFrom100(newval); - - ostringstream buf; - buf << "Custom '" << ourCustomAdjustables[myCurrentAdjustable].type - << "' set to " << newval << "%"; - - setPreset(myPreset); - return buf.str(); + text = msg.str(); + valueText = val.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/tv_filters/NTSCFilter.hxx b/src/common/tv_filters/NTSCFilter.hxx index f7e897916..c4fe30f15 100644 --- a/src/common/tv_filters/NTSCFilter.hxx +++ b/src/common/tv_filters/NTSCFilter.hxx @@ -92,8 +92,7 @@ class NTSCFilter // only 4 combinations are necessary string setNextAdjustable(); string setPreviousAdjustable(); - string increaseAdjustable(); - string decreaseAdjustable(); + void changeAdjustable(bool increase, string& text, string& valueText, Int32& value); // Load and save NTSC-related settings void loadConfig(const Settings& settings); diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index dda0c9fdd..33b7520be 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -349,14 +349,14 @@ bool Console::load(Serializer& in) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleFormat(int direction) +void Console::selectFormat(bool next) { string saveformat, message; uInt32 format = myCurrentFormat; - if(direction == 1) + if(next) format = (myCurrentFormat + 1) % 7; - else if(direction == -1) + else format = myCurrentFormat > 0 ? (myCurrentFormat - 1) : 6; setFormat(format); @@ -521,39 +521,20 @@ void Console::togglePhosphor() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::changePhosphor(int direction) +void Console::changePhosphor(bool increase) { int blend = BSPF::stringToInt(myProperties.get(PropType::Display_PPBlend)); - if(direction == +1) // increase blend - { - if(blend >= 100) - { - myOSystem.frameBuffer().showMessage("Phosphor blend at maximum"); - myOSystem.frameBuffer().tiaSurface().enablePhosphor(true, 100); - return; - } - else - blend = std::min(blend+2, 100); - } - else if(direction == -1) // decrease blend - { - if(blend <= 2) - { - myOSystem.frameBuffer().showMessage("Phosphor blend at minimum"); - myOSystem.frameBuffer().tiaSurface().enablePhosphor(true, 0); - return; - } - else - blend = std::max(blend-2, 0); - } - else - return; + if(increase) // increase blend + blend += 2; + else // decrease blend + blend -= 2; + blend = BSPF::clamp(blend, 0, 100); ostringstream val; val << blend; myProperties.set(PropType::Display_PPBlend, val.str()); - myOSystem.frameBuffer().showMessage("Phosphor blend " + val.str()); + myOSystem.frameBuffer().showMessage("Phosphor blend", val.str() + "%", blend); myOSystem.frameBuffer().tiaSurface().enablePhosphor(true, blend); } @@ -631,45 +612,25 @@ void Console::fry() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::changeVerticalCenter(int direction) +void Console::changeVerticalCenter(bool increase) { Int32 vcenter = myTIA->vcenter(); - if(direction == +1) // increase vcenter - { - if(vcenter >= myTIA->maxVcenter()) - { - myOSystem.frameBuffer().showMessage("V-Center at maximum"); - return; - } + if(increase) // increase vcenter ++vcenter; - } - else if(direction == -1) // decrease vcenter - { - if (vcenter <= myTIA->minVcenter()) - { - myOSystem.frameBuffer().showMessage("V-Center at minimum"); - return; - } + else // decrease vcenter --vcenter; - } - else - return; + vcenter = BSPF::clamp(vcenter, myTIA->minVcenter(), myTIA->maxVcenter()); - ostringstream ss; + ostringstream ss, val; ss << vcenter; myProperties.set(PropType::Display_VCenter, ss.str()); if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter); - ss.str(""); - ss << "V-Center "; - if (!vcenter) - ss << "default"; - else - ss << (vcenter > 0 ? "+" : "") << vcenter << "px"; - - myOSystem.frameBuffer().showMessage(ss.str()); + val << (vcenter ? vcenter > 0 ? "+" : "" : " ") << vcenter << "px"; + myOSystem.frameBuffer().showMessage("V-Center", val.str(), vcenter, + myTIA->minVcenter(), myTIA->maxVcenter()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -682,30 +643,15 @@ void Console::updateVcenter(Int32 vcenter) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::changeScanlineAdjust(int direction) +void Console::changeScanlineAdjust(bool increase) { Int32 newAdjustVSize = myTIA->adjustVSize(); - if (direction != -1 && direction != +1) return; - - if(direction == +1) // increase scanline adjustment - { - if (newAdjustVSize >= 5) - { - myOSystem.frameBuffer().showMessage("V-Size at maximum"); - return; - } + if(increase) // increase scanline adjustment newAdjustVSize++; - } - else if(direction == -1) // decrease scanline adjustment - { - if (newAdjustVSize <= -5) - { - myOSystem.frameBuffer().showMessage("V-Size at minimum"); - return; - } + else // decrease scanline adjustment newAdjustVSize--; - } + newAdjustVSize = BSPF::clamp(newAdjustVSize, -5, 5); if (newAdjustVSize != myTIA->adjustVSize()) { myTIA->setAdjustVSize(newAdjustVSize); @@ -713,15 +659,10 @@ void Console::changeScanlineAdjust(int direction) initializeVideo(); } - ostringstream ss; + ostringstream val; - ss << "V-Size "; - if (!newAdjustVSize) - ss << "default"; - else - ss << (newAdjustVSize > 0 ? "+" : "") << newAdjustVSize << "%"; - - myOSystem.frameBuffer().showMessage(ss.str()); + val << (newAdjustVSize ? newAdjustVSize > 0 ? "+" : "" : " ") << newAdjustVSize << "%"; + myOSystem.frameBuffer().showMessage("V-Size", val.str(), newAdjustVSize, -5, 5); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index ac26415d7..685297b55 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -189,9 +189,9 @@ class Console : public Serializable, public ConsoleIO /** Toggle between NTSC/PAL/SECAM (and variants) display format. - @param direction +1 indicates increase, -1 indicates decrease. + @param next Select next if true, else previous */ - void toggleFormat(int direction = 1); + void selectFormat(bool next = true); /** Set NTSC/PAL/SECAM (and variants) display format. @@ -222,9 +222,9 @@ class Console : public Serializable, public ConsoleIO /** Change the "Display.PPBlend" variable. - @param direction +1 indicates increase, -1 indicates decrease. + @param increase Increase if true, else decrease */ - void changePhosphor(int direction); + void changePhosphor(bool increase = true); /** Toggles the PAL color-loss effect. @@ -257,18 +257,18 @@ class Console : public Serializable, public ConsoleIO /** Change the "Display.VCenter" variable. - @param direction +1 indicates increase, -1 indicates decrease. + @param increase Increase if true, else decrease */ - void changeVerticalCenter(int direction); + void changeVerticalCenter(bool increase = true); /** Change the "TIA scanline adjust" variable. Note that there are currently two of these (NTSC and PAL). The currently active mode will determine which one is used. - @param direction +1 indicates increase, -1 indicates decrease. + @param increase Increase if true, else decrease */ - void changeScanlineAdjust(int direction); + void changeScanlineAdjust(bool increase = true); /** Returns the current framerate. diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 362625909..82fd4280c 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -413,27 +413,27 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::VidmodeDecrease: - if(pressed) myOSystem.frameBuffer().changeVidMode(-1); + if(pressed) myOSystem.frameBuffer().selectVidMode(false); return; case Event::VidmodeIncrease: - if(pressed) myOSystem.frameBuffer().changeVidMode(+1); + if(pressed) myOSystem.frameBuffer().selectVidMode(true); return; case Event::VCenterDecrease: - if (pressed) myOSystem.console().changeVerticalCenter(-1); + if (pressed) myOSystem.console().changeVerticalCenter(false); return; case Event::VCenterIncrease: - if (pressed) myOSystem.console().changeVerticalCenter(+1); + if (pressed) myOSystem.console().changeVerticalCenter(true); return; case Event::ScanlineAdjustDecrease: - if (pressed) myOSystem.console().changeScanlineAdjust(-1); + if (pressed) myOSystem.console().changeScanlineAdjust(false); return; case Event::ScanlineAdjustIncrease: - if (pressed) myOSystem.console().changeScanlineAdjust(+1); + if (pressed) myOSystem.console().changeScanlineAdjust(true); return; case Event::PreviousPaletteAttribute: @@ -457,11 +457,11 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::OverscanDecrease: - if (pressed) myOSystem.frameBuffer().changeOverscan(-1); + if (pressed) myOSystem.frameBuffer().changeOverscan(false); return; case Event::OverscanIncrease: - if (pressed) myOSystem.frameBuffer().changeOverscan(1); + if (pressed) myOSystem.frameBuffer().changeOverscan(true); return; case Event::PreviousVideoMode: @@ -525,27 +525,33 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) case Event::DecreaseAttribute: if (pressed) { + string text, valueText; + Int32 newVal; + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::CUSTOM); - myOSystem.frameBuffer().showMessage( - myOSystem.frameBuffer().tiaSurface().ntsc().decreaseAdjustable()); + myOSystem.frameBuffer().tiaSurface().ntsc().changeAdjustable(false, text, valueText, newVal); + myOSystem.frameBuffer().showMessage(text, valueText, newVal); } return; case Event::IncreaseAttribute: if (pressed) { + string text, valueText; + Int32 newVal; + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::CUSTOM); - myOSystem.frameBuffer().showMessage( - myOSystem.frameBuffer().tiaSurface().ntsc().increaseAdjustable()); + myOSystem.frameBuffer().tiaSurface().ntsc().changeAdjustable(true, text, valueText, newVal); + myOSystem.frameBuffer().showMessage(text, valueText, newVal); } return; case Event::PhosphorDecrease: - if (pressed) myOSystem.console().changePhosphor(-1); + if (pressed) myOSystem.console().changePhosphor(false); return; case Event::PhosphorIncrease: - if (pressed) myOSystem.console().changePhosphor(1); + if (pressed) myOSystem.console().changePhosphor(true); return; case Event::TogglePhosphor: @@ -603,11 +609,11 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::FormatDecrease: - if (pressed) myOSystem.console().toggleFormat(-1); + if (pressed) myOSystem.console().selectFormat(false); return; case Event::FormatIncrease: - if (pressed) myOSystem.console().toggleFormat(1); + if (pressed) myOSystem.console().selectFormat(true); return; case Event::ToggleGrabMouse: diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 14f620373..254060054 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -309,7 +309,12 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, } if(!myMsg.surface) - myMsg.surface = allocateSurface(font().getMaxCharWidth() * 56, font().getFontHeight() * 1.5); + { + const int fontWidth = font().getMaxCharWidth(), + HBORDER = fontWidth * 1.25 / 2.0; + myMsg.surface = allocateSurface(fontWidth * MESSAGE_WIDTH + HBORDER * 2, + font().getFontHeight() * 1.5); + } #endif // Print initial usage message, but only print it later if the status has changed @@ -500,19 +505,62 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, const int VBORDER = fontHeight / 4; const int HBORDER = fontWidth * 1.25 / 2.0; - // Precompute the message coordinates - myMsg.text = message; - myMsg.counter = uInt32(myOSystem.frameRate()) << 1; // Show message for 2 seconds - if(myMsg.counter == 0) myMsg.counter = 60; - myMsg.color = kBtnTextColor; + myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds + if(myMsg.counter == 0) + myMsg.counter = 120; - myMsg.w = font().getStringWidth(myMsg.text) + HBORDER * 2; - myMsg.h = fontHeight + VBORDER * 2; + // Precompute the message coordinates + myMsg.text = message; + myMsg.color = kBtnTextColor; + myMsg.showGauge = false; + myMsg.w = font().getStringWidth(myMsg.text) + HBORDER * 2; + myMsg.h = fontHeight + VBORDER * 2; + myMsg.position = position; + myMsg.enabled = true; + + myMsg.surface->setSrcSize(myMsg.w, myMsg.h); + myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); +#endif +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::showMessage(const string& message, const string& valueText, + float value, float minValue, float maxValue) +{ +#ifdef GUI_SUPPORT + // Only show messages if they've been enabled + if(myMsg.surface == nullptr || !myOSystem.settings().getBool("uimessages")) + return; + + const int fontWidth = font().getMaxCharWidth(), + fontHeight = font().getFontHeight(); + const int VBORDER = fontHeight / 4; + const int HBORDER = fontWidth * 1.25 / 2.0; + + myMsg.counter = uInt32(myOSystem.frameRate()) * 5; // Show message for 5 seconds + if(myMsg.counter == 0) + myMsg.counter = 120; + + // Precompute the message coordinates + myMsg.text = message; + myMsg.color = kBtnTextColor; + myMsg.showGauge = true; + if(maxValue - minValue != 0) + myMsg.value = (value - minValue) / (maxValue - minValue) * 100.F; + else + myMsg.value = 100.F; + myMsg.valueText = valueText; + myMsg.w = std::min(fontWidth * MESSAGE_WIDTH, + font().getStringWidth(myMsg.text) + + fontWidth * (GAUGEBAR_WIDTH + 2) + + font().getStringWidth(myMsg.valueText)) + + HBORDER * 2; + myMsg.h = fontHeight + VBORDER * 2; + myMsg.position = MessagePosition::BottomCenter; + myMsg.enabled = true; myMsg.surface->setSrcSize(myMsg.w, myMsg.h); myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); - myMsg.position = position; - myMsg.enabled = true; #endif } @@ -631,6 +679,7 @@ inline bool FrameBuffer::drawMessage() fontHeight = font().getFontHeight(); const int VBORDER = fontHeight / 4; const int HBORDER = fontWidth * 1.25 / 2.0; + constexpr int BORDER = 1; switch(myMsg.position) { @@ -681,10 +730,44 @@ inline bool FrameBuffer::drawMessage() } myMsg.surface->setDstPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y()); - myMsg.surface->fillRect(1, 1, myMsg.w - 2, myMsg.h - 2, kBtnColor); - myMsg.surface->frameRect(0, 0, myMsg.w, myMsg.h, kColor); + myMsg.surface->fillRect(0, 0, myMsg.w, myMsg.h, kColor); + myMsg.surface->fillRect(BORDER, BORDER, myMsg.w - BORDER * 2, myMsg.h - BORDER * 2, kBtnColor); myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER, myMsg.w, myMsg.color); + + if(myMsg.showGauge) + { + constexpr int NUM_TICKMARKS = 4; + // limit gauge bar width if texts are too long + const int swidth = std::min(fontWidth * GAUGEBAR_WIDTH, + fontWidth * (MESSAGE_WIDTH - 2) + - font().getStringWidth(myMsg.text) + - font().getStringWidth(myMsg.valueText)); + const int bwidth = swidth * myMsg.value / 100.F; + const int bheight = fontHeight >> 1; + const int x = HBORDER + font().getStringWidth(myMsg.text) + fontWidth; + // align bar with bottom of text + const int y = VBORDER + font().desc().ascent - bheight; + + // draw bar gauge + myMsg.surface->fillRect(x - BORDER, y, swidth + BORDER * 2, bheight, kSliderBGColor); + myMsg.surface->fillRect(x, y + BORDER, bwidth, bheight - BORDER * 2, kSliderColor); + // draw tickmark in the middle of the bar + for(int i = 1; i < NUM_TICKMARKS; ++i) + { + ColorId color; + int xt = x + swidth * i / NUM_TICKMARKS; + if(bwidth < xt - x) + color = kCheckColor; // kSliderColor; + else + color = kSliderBGColor; + myMsg.surface->vLine(xt, y + bheight / 2, y + bheight - 1, color); + } + // draw value text + myMsg.surface->drawString(font(), myMsg.valueText, + x + swidth + fontWidth, VBORDER, + myMsg.w, myMsg.color); + } myMsg.surface->render(); myMsg.counter--; #endif @@ -900,12 +983,12 @@ void FrameBuffer::toggleFullscreen() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::changeOverscan(int direction) +void FrameBuffer::changeOverscan(bool increase) { if (fullScreen()) { int oldOverscan = myOSystem.settings().getInt("tia.fs_overscan"); - int overscan = BSPF::clamp(oldOverscan + direction, 0, 10); + int overscan = BSPF::clamp(oldOverscan + (increase ? 1 : -1), 0, 10); if (overscan != oldOverscan) { @@ -914,14 +997,15 @@ void FrameBuffer::changeOverscan(int direction) // issue a complete framebuffer re-initialization myOSystem.createFrameBuffer(); } - ostringstream msg; - msg << "Overscan at " << overscan << "%"; - showMessage(msg.str()); + + ostringstream val; + val << (overscan ? overscan > 0 ? "+" : "" : " ") << overscan << "%"; + myOSystem.frameBuffer().showMessage("Overscan", val.str(), overscan, 0, 10); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBuffer::changeVidMode(int direction) +bool FrameBuffer::selectVidMode(bool next) { EventHandlerState state = myOSystem.eventHandler().state(); bool tiaMode = (state != EventHandlerState::DEBUGGER && @@ -931,12 +1015,10 @@ bool FrameBuffer::changeVidMode(int direction) if(!tiaMode) return false; - if(direction == +1) + if(next) myCurrentModeList->next(); - else if(direction == -1) - myCurrentModeList->previous(); else - return false; + myCurrentModeList->previous(); saveCurrentWindowPosition(); @@ -956,7 +1038,7 @@ bool FrameBuffer::changeVidMode(int direction) myTIASurface->initialize(myOSystem.console(), mode); resetSurfaces(); - showMessage(mode.description); + showMessage("Zoom", mode.description, mode.zoom, supportedTIAMinZoom(), myTIAMaxZoom); myOSystem.sound().mute(oldMuteState); if(fullScreen()) @@ -1077,7 +1159,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS) { ostringstream desc; - desc << "Zoom " << zoom << "x"; + desc << (zoom * 100) << "%"; VideoMode mode(baseWidth*zoom, baseHeight*zoom, baseWidth*zoom, baseHeight*zoom, VideoMode::Stretch::Fill, 1.0, desc.str(), zoom); diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index a73b01ffb..7a73b3d90 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -147,6 +147,17 @@ class FrameBuffer void showMessage(const string& message, MessagePosition position = MessagePosition::BottomCenter, bool force = false); + /** + Shows a message with a bar gauge onscreen. + + @param message The message to be shown + @param valueText The value of the bar gauge as text + @param value The bar gauge percentage + @param minValue The minimal value of the bar gauge + @param maxValue The maximal value of the bar gauge + */ + void showMessage(const string& message, const string& valueText, + float value, float minValue = 0.F, float maxValue = 100.F); /** Toggles showing or hiding framerate statistics. @@ -251,10 +262,10 @@ class FrameBuffer /** Changes the fullscreen overscan. - direction = -1 means less overscan - direction = +1 means more overscan + + @param increase Increase if true, else decrease */ - void changeOverscan(int direction); + void changeOverscan(bool increase = true); /** This method is called when the user wants to switch to the next @@ -264,9 +275,9 @@ class FrameBuffer direction = -1 means go to the next lower video mode direction = +1 means go to the next higher video mode - @param direction Described above + @param next Select next if true, else previous */ - bool changeVidMode(int direction); + bool selectVidMode(bool next = true); /** Sets the state of the cursor (hidden or grabbed) based on the @@ -502,6 +513,11 @@ class FrameBuffer OSystem& myOSystem; private: + // Maximum message width [chars] + static constexpr int MESSAGE_WIDTH = 56; + // Maximum gauge bar width [chars] + static constexpr int GAUGEBAR_WIDTH = 30; + /** Draw pending messages. @@ -648,6 +664,9 @@ class FrameBuffer ColorId color{kNone}; shared_ptr surface; bool enabled{false}; + bool showGauge{false}; + float value{0.0F}; + string valueText; }; Message myMsg; Message myStatsMsg; diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index 8ff9f3e17..53060a97e 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -231,21 +231,11 @@ void TIASurface::setScanlineIntensity(int amount) ostringstream buf; uInt32 intensity = enableScanlines(amount); - if(intensity == 0) - buf << "Scanlines disabled"; - else - { - buf << "Scanline intensity at "; - if(intensity < 100) - buf << intensity << "%"; - else - buf << "maximum"; - } myOSystem.settings().setValue("tv.scanlines", intensity); - enableNTSC(ntscEnabled()); - myFB.showMessage(buf.str()); + buf << intensity << "%"; + myFB.showMessage("Scanline intensity", buf.str(), intensity); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/CommandDialog.cxx b/src/gui/CommandDialog.cxx index 5790f7193..e4c5f610a 100644 --- a/src/gui/CommandDialog.cxx +++ b/src/gui/CommandDialog.cxx @@ -199,7 +199,7 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd, // Column 3 case kFormatCmd: - instance().console().toggleFormat(); + instance().console().selectFormat(); updateTVFormat(); break; diff --git a/src/gui/MinUICommandDialog.cxx b/src/gui/MinUICommandDialog.cxx index b93b95890..080316005 100644 --- a/src/gui/MinUICommandDialog.cxx +++ b/src/gui/MinUICommandDialog.cxx @@ -217,7 +217,7 @@ void MinUICommandDialog::handleCommand(CommandSender* sender, int cmd, // Column 3 case kFormatCmd: - instance().console().toggleFormat(); + instance().console().selectFormat(); updateTVFormat(); break;