From 5fa9936aab36aa16290ce80b217db0333fe05cfd Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 18 May 2020 12:26:05 +0200 Subject: [PATCH 001/104] added optional refresh rate adaption in fullscreen mode --- src/common/FrameBufferSDL2.cxx | 65 ++++++++++++++++++++++++++++++++++ src/common/FrameBufferSDL2.hxx | 8 +++++ src/emucore/FrameBuffer.hxx | 8 +++++ src/emucore/Settings.cxx | 1 + src/gui/VideoAudioDialog.cxx | 12 +++++++ src/gui/VideoAudioDialog.hxx | 1 + 6 files changed, 95 insertions(+) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 4d013a35d..a1a9c5bbd 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -340,9 +340,74 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) myOSystem.settings().setValue("video", renderinfo.name); + adaptRefreshRate(); + return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FrameBufferSDL2::adaptRefreshRate() +{ + const bool adapt = myOSystem.settings().getBool("tia.refresh"); + + // adapt only in emulation (and debugger?) and fullscreen mode + // TODO: adapt while creating new window + if(adapt && fullScreen() + && (myBufferType == BufferType::Emulator/* || myBufferType == BufferType::Debugger*/)) + { + SDL_DisplayMode sdlMode; + + if(SDL_GetWindowDisplayMode(myWindow, &sdlMode) != 0) + { + Logger::error("Display mode could not be retrieved"); + return false; + } + + const int currentRefreshRate = sdlMode.refresh_rate; + const string format = myOSystem.console().getFormatString(); + const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; + + sdlMode.refresh_rate = isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too + + if(currentRefreshRate != sdlMode.refresh_rate) + { + const int display = SDL_GetWindowDisplayIndex(myWindow); + SDL_DisplayMode closestSdlMode; + + if(SDL_GetClosestDisplayMode(display, &sdlMode, &closestSdlMode) == NULL) + { + Logger::error("Closest display mode could not be retrieved"); + return false; + } + // Note: Modes are scanned with size being first priority, + // therefore the size will never change. + // Only change if the display supports a better refresh rate + if(currentRefreshRate != closestSdlMode.refresh_rate) + { + // Switch to new mode + if(SDL_SetWindowDisplayMode(myWindow, &closestSdlMode) != 0) + { + Logger::error("Display refresh rate change failed"); + return false; + } + // Any change only works in real fullscreen mode! + if(SDL_SetWindowFullscreen(myWindow, SDL_WINDOW_FULLSCREEN) != 0) + { + Logger::error("Display fullscreen change failed"); + return false; + } + ostringstream msg; + + msg << "Display refresh rate changed from " << currentRefreshRate << "Hz to " + << closestSdlMode.refresh_rate << "Hz"; + Logger::info(msg.str()); + return true; + } + } + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSDL2::setTitle(const string& title) { diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index d2825037c..0d74d100b 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -181,6 +181,14 @@ class FrameBufferSDL2 : public FrameBuffer */ bool setVideoMode(const string& title, const VideoMode& mode) override; + + /** + Adapt display refresh rate to game refresh rate in (real) fullscreen mode + + @return True if the refresh rate was changed + */ + bool adaptRefreshRate(); + /** This method is called to create a surface with the given attributes. diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 3912f38cd..e19fcc335 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -81,6 +81,13 @@ class FrameBuffer } }; + struct DisplayMode + { + uInt32 display; + Common::Size size; + uInt32 refresh_rate; + }; + enum class BufferType { None, Launcher, @@ -439,6 +446,7 @@ class FrameBuffer virtual int scaleY(int y) const { return y; } protected: + /** This method is called to query and initialize the video hardware for desktop and fullscreen resolution information. Since several diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index f5e120408..bbcc0c4bd 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -54,6 +54,7 @@ Settings::Settings() setPermanent("tia.fs_stretch", "false"); setPermanent("tia.fs_overscan", "0"); setPermanent("tia.vsizeadjust", 0); + setPermanent("tia.refresh", "false"); setPermanent("tia.dbgcolors", "roygpb"); // Palette options setPermanent("palette", PaletteHandler::SETTING_STANDARD); diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 48fdcc8de..74b326f7c 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -166,9 +166,14 @@ void VideoAudioDialog::addDisplayTab() myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10); myTVOverscan->setTickmarkIntervals(2); wid.push_back(myTVOverscan); + + // Adapt refresh rate ypos += lineHeight + VGAP; + myRefreshAdjust = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt refresh rate"); + wid.push_back(myRefreshAdjust); // Vertical size + ypos += lineHeight + VGAP; myVSizeAdjust = new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, "V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true); @@ -176,6 +181,7 @@ void VideoAudioDialog::addDisplayTab() myVSizeAdjust->setTickmarkIntervals(2); wid.push_back(myVSizeAdjust); + // Add items for tab 0 addToFocusList(wid, myTab, tabID); } @@ -486,6 +492,8 @@ void VideoAudioDialog::loadConfig() myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); // Fullscreen overscan setting myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan")); + // Adapt refresh rate + myRefreshAdjust->setState(instance().settings().getBool("tia.refresh")); handleFullScreenChange(); // Aspect ratio setting (NTSC and PAL) @@ -597,6 +605,8 @@ void VideoAudioDialog::saveConfig() instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); // Fullscreen overscan instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel()); + // Adapt refresh rate + instance().settings().setValue("tia.refresh", myRefreshAdjust->getState()); // TIA zoom levels instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0); @@ -709,6 +719,7 @@ void VideoAudioDialog::setDefaults() //myFullScreenMode->setSelectedIndex(0); myUseStretch->setState(false); myTVOverscan->setValue(0); + myRefreshAdjust->setState(false); myTIAZoom->setValue(300); myVSizeAdjust->setValue(0); @@ -834,6 +845,7 @@ void VideoAudioDialog::handleFullScreenChange() bool enable = myFullscreen->getState(); myUseStretch->setEnabled(enable); myTVOverscan->setEnabled(enable); + myRefreshAdjust->setEnabled(enable); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index f46740ae6..6764bc556 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -74,6 +74,7 @@ class VideoAudioDialog : public Dialog //PopUpWidget* myFullScreenMode; CheckboxWidget* myUseStretch{nullptr}; SliderWidget* myTVOverscan{nullptr}; + CheckboxWidget* myRefreshAdjust{nullptr}; SliderWidget* myTIAZoom{nullptr}; SliderWidget* myVSizeAdjust{nullptr}; From 2bf7421d1b206c81e91e355dfee999103b5a8d13 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 18 May 2020 21:13:18 +0200 Subject: [PATCH 002/104] improved refresh rate code --- src/common/FrameBufferSDL2.cxx | 130 +++++++++++++++++++-------------- src/common/FrameBufferSDL2.hxx | 16 +++- src/emucore/FrameBuffer.cxx | 10 ++- src/emucore/FrameBuffer.hxx | 5 ++ src/emucore/Settings.cxx | 3 +- src/gui/VideoAudioDialog.cxx | 28 +++---- src/gui/VideoAudioDialog.hxx | 3 +- 7 files changed, 115 insertions(+), 80 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index a1a9c5bbd..37d2e5499 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -218,6 +218,10 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(SDL_WasInit(SDL_INIT_VIDEO) == 0) return false; + const bool fullScreen = mode.fsIndex != -1; + const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") + && refreshRate() != gameRefreshRate(); + // TODO: On multiple displays, switching from centered mode, does not respect // current window's display (which many not be centered anymore) @@ -261,8 +265,11 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) posX = BSPF::clamp(posX, x0 - Int32(mode.screen.w) + 50, x1 - 50); posY = BSPF::clamp(posY, y0 + 50, y1 - 50); } - uInt32 flags = mode.fsIndex != -1 ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; - flags |= SDL_WINDOW_ALLOW_HIGHDPI; + + SDL_DisplayMode adaptedSdlMode; + const bool adaptRefresh = shouldAdapt && adaptRefreshRate(displayIndex, adaptedSdlMode); + const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI + | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0); // macOS seems to have issues with destroying the window, and wants to // keep the same handle @@ -278,12 +285,14 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) int w, h; SDL_GetWindowSize(myWindow, &w, &h); - if(d != displayIndex || uInt32(w) != mode.screen.w || uInt32(h) != mode.screen.h) + if(d != displayIndex || uInt32(w) != mode.screen.w || uInt32(h) != mode.screen.h + || shouldAdapt) { SDL_DestroyWindow(myWindow); myWindow = nullptr; } } + if(myWindow) { // Even though window size stayed the same, the title may have changed @@ -312,8 +321,24 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) Logger::error(msg); return false; } + setWindowIcon(); } + if(adaptRefresh) + { + // Switch to mode for adapted refresh rate + if(SDL_SetWindowDisplayMode(myWindow, &adaptedSdlMode) != 0) + { + Logger::error("Display refresh rate change failed"); + } + else + { + ostringstream msg; + + msg << "Display refresh rate changed to " << adaptedSdlMode.refresh_rate << "Hz"; + Logger::info(msg.str()); + } + } uInt32 renderFlags = SDL_RENDERER_ACCELERATED; if(myOSystem.settings().getBool("vsync") @@ -340,70 +365,35 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) myOSystem.settings().setValue("video", renderinfo.name); - adaptRefreshRate(); - return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSDL2::adaptRefreshRate() +bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& closestSdlMode) { - const bool adapt = myOSystem.settings().getBool("tia.refresh"); + SDL_DisplayMode sdlMode; - // adapt only in emulation (and debugger?) and fullscreen mode - // TODO: adapt while creating new window - if(adapt && fullScreen() - && (myBufferType == BufferType::Emulator/* || myBufferType == BufferType::Debugger*/)) + if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) { - SDL_DisplayMode sdlMode; + Logger::error("Display mode could not be retrieved"); + return false; + } - if(SDL_GetWindowDisplayMode(myWindow, &sdlMode) != 0) + const int currentRefreshRate = sdlMode.refresh_rate; + + sdlMode.refresh_rate = gameRefreshRate(); + + if(currentRefreshRate != sdlMode.refresh_rate) + { + // Note: Modes are scanned with size being first priority, + // therefore the size will never change. + if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == NULL) { - Logger::error("Display mode could not be retrieved"); + Logger::error("Closest display mode could not be retrieved"); return false; } - - const int currentRefreshRate = sdlMode.refresh_rate; - const string format = myOSystem.console().getFormatString(); - const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - - sdlMode.refresh_rate = isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too - - if(currentRefreshRate != sdlMode.refresh_rate) - { - const int display = SDL_GetWindowDisplayIndex(myWindow); - SDL_DisplayMode closestSdlMode; - - if(SDL_GetClosestDisplayMode(display, &sdlMode, &closestSdlMode) == NULL) - { - Logger::error("Closest display mode could not be retrieved"); - return false; - } - // Note: Modes are scanned with size being first priority, - // therefore the size will never change. - // Only change if the display supports a better refresh rate - if(currentRefreshRate != closestSdlMode.refresh_rate) - { - // Switch to new mode - if(SDL_SetWindowDisplayMode(myWindow, &closestSdlMode) != 0) - { - Logger::error("Display refresh rate change failed"); - return false; - } - // Any change only works in real fullscreen mode! - if(SDL_SetWindowFullscreen(myWindow, SDL_WINDOW_FULLSCREEN) != 0) - { - Logger::error("Display fullscreen change failed"); - return false; - } - ostringstream msg; - - msg << "Display refresh rate changed from " << currentRefreshRate << "Hz to " - << closestSdlMode.refresh_rate << "Hz"; - Logger::info(msg.str()); - return true; - } - } + // Only change if the display supports a better refresh rate + return currentRefreshRate != closestSdlMode.refresh_rate; } return false; } @@ -469,6 +459,34 @@ bool FrameBufferSDL2::fullScreen() const #endif } +int FrameBufferSDL2::refreshRate() const +{ + ASSERT_MAIN_THREAD; + + const uInt32 displayIndex = SDL_GetWindowDisplayIndex(myWindow); + SDL_DisplayMode sdlMode; + + if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) == 0) + return sdlMode.refresh_rate; + + if (myWindow != NULL) + Logger::error("Could not retrieve current display mode"); + return 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int FrameBufferSDL2::gameRefreshRate() const +{ + if(myOSystem.hasConsole()) + { + const string format = myOSystem.console().getFormatString(); + const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; + + return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too + } + return 60; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSDL2::renderToScreen() { diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 0d74d100b..f0d69bc96 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -183,11 +183,11 @@ class FrameBufferSDL2 : public FrameBuffer /** - Adapt display refresh rate to game refresh rate in (real) fullscreen mode + Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode - @return True if the refresh rate was changed + @return True if the refresh rate should be changed */ - bool adaptRefreshRate(); + bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& closestSdlMode); /** This method is called to create a surface with the given attributes. @@ -241,6 +241,16 @@ class FrameBufferSDL2 : public FrameBuffer */ void determineDimensions(); + /** + Retrieve the current display's refresh rate, or 0 if no window + */ + int refreshRate() const override; + + /** + Retrieve the current game's refresh rate, or 60 if no game + */ + int gameRefreshRate() const; + private: // The SDL video buffer SDL_Window* myWindow{nullptr}; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 4599a3860..2d495c101 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -993,7 +993,15 @@ void FrameBuffer::toggleFullscreen(bool toggle) setFullscreen(isFullscreen); - showMessage(string("Fullscreen ") + (isFullscreen ? "enabled" : "disabled")); + ostringstream msg; + + msg << "Fullscreen "; + if(isFullscreen) + msg << "enabled (" << refreshRate() << " Hz)"; + else + msg << "disabled"; + + showMessage(msg.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index e19fcc335..945cbb780 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -518,6 +518,11 @@ class FrameBuffer */ virtual string about() const = 0; + /** + Retrieve the current display's refresh rate + */ + virtual int refreshRate() const { return 0; } + protected: // The parent system for the framebuffer OSystem& myOSystem; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index bbcc0c4bd..dca79717d 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -52,9 +52,9 @@ Settings::Settings() setPermanent("tia.zoom", "3"); setPermanent("fullscreen", "false"); setPermanent("tia.fs_stretch", "false"); + setPermanent("tia.fs_refresh", "false"); setPermanent("tia.fs_overscan", "0"); setPermanent("tia.vsizeadjust", 0); - setPermanent("tia.refresh", "false"); setPermanent("tia.dbgcolors", "roygpb"); // Palette options setPermanent("palette", PaletteHandler::SETTING_STANDARD); @@ -442,6 +442,7 @@ void Settings::usage() const << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA\n" << " image\n" << " -tia.fs_stretch <1|0> Stretch TIA image to fill fullscreen mode\n" + << " -tia.fs_refresh <1|0> Try to adapt display refresh rate to game\n" << " -tia.fs_overscan <0-10> Add overscan to TIA image in fullscreen mode\n" << " -tia.dbgcolors Debug colors to use for each object (see manual\n" << " for description)\n" diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 74b326f7c..46203783a 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -149,29 +149,23 @@ void VideoAudioDialog::addDisplayTab() wid.push_back(myFullscreen); ypos += lineHeight + VGAP; - /*pwidth = font.getStringWidth("0: 3840x2860@120Hz"); - myFullScreenMode = new PopUpWidget(myTab, font, xpos + INDENT + 2, ypos, pwidth, lineHeight, - instance().frameBuffer().supportedScreenModes(), "Mode "); - wid.push_back(myFullScreenMode); - ypos += lineHeight + VGAP;*/ - // FS stretch myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); wid.push_back(myUseStretch); + + // Adapt refresh rate ypos += lineHeight + VGAP; + myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); + wid.push_back(myRefreshAdapt); // FS overscan + ypos += lineHeight + VGAP; myTVOverscan = new SliderWidget(myTab, _font, xpos + INDENT, ypos - 1, swidth, lineHeight, "Overscan", lwidth - INDENT, kOverscanChanged, fontWidth * 3, "%"); myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10); myTVOverscan->setTickmarkIntervals(2); wid.push_back(myTVOverscan); - // Adapt refresh rate - ypos += lineHeight + VGAP; - myRefreshAdjust = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt refresh rate"); - wid.push_back(myRefreshAdjust); - // Vertical size ypos += lineHeight + VGAP; myVSizeAdjust = @@ -490,10 +484,10 @@ void VideoAudioDialog::loadConfig() myFullScreenMode->setSelected(mode);*/ // Fullscreen stretch setting myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); + // Adapt refresh rate + myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh")); // Fullscreen overscan setting myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan")); - // Adapt refresh rate - myRefreshAdjust->setState(instance().settings().getBool("tia.refresh")); handleFullScreenChange(); // Aspect ratio setting (NTSC and PAL) @@ -603,10 +597,10 @@ void VideoAudioDialog::saveConfig() instance().settings().setValue("fullscreen", myFullscreen->getState()); // Fullscreen stretch setting instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); + // Adapt refresh rate + instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState()); // Fullscreen overscan instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel()); - // Adapt refresh rate - instance().settings().setValue("tia.refresh", myRefreshAdjust->getState()); // TIA zoom levels instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0); @@ -718,8 +712,8 @@ void VideoAudioDialog::setDefaults() myFullscreen->setState(false); //myFullScreenMode->setSelectedIndex(0); myUseStretch->setState(false); + myRefreshAdapt->setState(false); myTVOverscan->setValue(0); - myRefreshAdjust->setState(false); myTIAZoom->setValue(300); myVSizeAdjust->setValue(0); @@ -844,8 +838,8 @@ void VideoAudioDialog::handleFullScreenChange() { bool enable = myFullscreen->getState(); myUseStretch->setEnabled(enable); + myRefreshAdapt->setEnabled(enable); myTVOverscan->setEnabled(enable); - myRefreshAdjust->setEnabled(enable); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 6764bc556..0961f776e 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -71,10 +71,9 @@ class VideoAudioDialog : public Dialog PopUpWidget* myRenderer{nullptr}; CheckboxWidget* myTIAInterpolate{nullptr}; CheckboxWidget* myFullscreen{nullptr}; - //PopUpWidget* myFullScreenMode; CheckboxWidget* myUseStretch{nullptr}; SliderWidget* myTVOverscan{nullptr}; - CheckboxWidget* myRefreshAdjust{nullptr}; + CheckboxWidget* myRefreshAdapt{nullptr}; SliderWidget* myTIAZoom{nullptr}; SliderWidget* myVSizeAdjust{nullptr}; From 41d217e17d32853f129689d13313eb11da62c289 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 19 May 2020 08:53:11 +0200 Subject: [PATCH 003/104] fix window position saving when switching from/to fullscreen mode suppress fullscreen UI message outside emulation mode --- src/common/FrameBufferSDL2.cxx | 2 +- src/emucore/FrameBuffer.cxx | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 37d2e5499..8a943332c 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -482,7 +482,7 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too + return isNtsc ? 75 : 50; // TODO: check for multiples e.g. 120/100 too } return 60; } diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 2d495c101..88f62517f 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -959,6 +959,7 @@ void FrameBuffer::setFullscreen(bool enable) default: return; } + saveCurrentWindowPosition(); // Changing the video mode can take some time, during which the last // sound played may get 'stuck' @@ -993,15 +994,18 @@ void FrameBuffer::toggleFullscreen(bool toggle) setFullscreen(isFullscreen); - ostringstream msg; + if(myBufferType == BufferType::Emulator) + { + ostringstream msg; - msg << "Fullscreen "; - if(isFullscreen) - msg << "enabled (" << refreshRate() << " Hz)"; - else - msg << "disabled"; + msg << "Fullscreen "; + if(isFullscreen) + msg << "enabled (" << refreshRate() << " Hz)"; + else + msg << "disabled"; - showMessage(msg.str()); + showMessage(msg.str()); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From cde78a779669a34a201baf92daaf05135e1ccd7b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 19 May 2020 10:19:48 +0200 Subject: [PATCH 004/104] oops --- src/common/FrameBufferSDL2.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 8a943332c..37d2e5499 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -482,7 +482,7 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 75 : 50; // TODO: check for multiples e.g. 120/100 too + return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too } return 60; } From 5aca14c2481b8e27d55162e3eca656cc56c163cf Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 19 May 2020 12:33:01 +0200 Subject: [PATCH 005/104] try to create renderer only when required (needs testing) --- src/common/FrameBufferSDL2.cxx | 92 +++++++++++++++++++++++++++------- src/common/FrameBufferSDL2.hxx | 8 +++ 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 37d2e5499..c977405fa 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -221,6 +221,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) const bool fullScreen = mode.fsIndex != -1; const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") && refreshRate() != gameRefreshRate(); + bool forceCreateRenderer = false; // TODO: On multiple displays, switching from centered mode, does not respect // current window's display (which many not be centered anymore) @@ -230,12 +231,12 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) // Get windowed window's last position myWindowedPos = myOSystem.settings().getPoint(getPositionKey()); - // Always recreate renderer (some systems need this) - if(myRenderer) - { - SDL_DestroyRenderer(myRenderer); - myRenderer = nullptr; - } + //// Always recreate renderer (some systems need this) + //if(myRenderer) + //{ + // SDL_DestroyRenderer(myRenderer); + // myRenderer = nullptr; + //} int posX, posY; @@ -313,6 +314,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) #endif else { + forceCreateRenderer = true; myWindow = SDL_CreateWindow(title.c_str(), posX, posY, mode.screen.w, mode.screen.h, flags); if(myWindow == nullptr) @@ -340,24 +342,78 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) } } + return createRenderer(forceCreateRenderer); + + //uInt32 renderFlags = SDL_RENDERER_ACCELERATED; + //if(myOSystem.settings().getBool("vsync") + // && !myOSystem.settings().getBool("turbo")) // V'synced blits option + // renderFlags |= SDL_RENDERER_PRESENTVSYNC; + //const string& video = myOSystem.settings().getString("video"); // Render hint + //if(video != "") + // SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); + + //myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); + + //detectFeatures(); + //determineDimensions(); + + //if(myRenderer == nullptr) + //{ + // string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); + // Logger::error(msg); + // return false; + //} + //clear(); + + //SDL_RendererInfo renderinfo; + //if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) + // myOSystem.settings().setValue("video", renderinfo.name); + + //return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FrameBufferSDL2::createRenderer(bool force) +{ + // A new renderer is only created when necessary: + // - new myWindow (force = true) + // - no renderer existing + // - different renderer flags + // - different renderer name + bool recreate = force || myRenderer == nullptr; uInt32 renderFlags = SDL_RENDERER_ACCELERATED; + const string& video = myOSystem.settings().getString("video"); // Render hint + SDL_RendererInfo renderInfo; + if(myOSystem.settings().getBool("vsync") && !myOSystem.settings().getBool("turbo")) // V'synced blits option renderFlags |= SDL_RENDERER_PRESENTVSYNC; - const string& video = myOSystem.settings().getString("video"); // Render hint - if(video != "") - SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); - myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); + // check renderer flags and name + recreate |= (SDL_GetRendererInfo(myRenderer, &renderInfo) != 0) + || ((renderInfo.flags & (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) != renderFlags + || (video != renderInfo.name)); - detectFeatures(); - determineDimensions(); - - if(myRenderer == nullptr) + if(recreate) { - string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); - Logger::error(msg); - return false; + cerr << "Create new renderer " << int(myBufferType) << endl; + if(myRenderer) + SDL_DestroyRenderer(myRenderer); + + if(video != "") + SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); + + myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); + + detectFeatures(); + determineDimensions(); + + if(myRenderer == nullptr) + { + string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); + Logger::error(msg); + return false; + } } clear(); @@ -482,7 +538,7 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too + return isNtsc ? 75 : 50; // TODO: check for multiples e.g. 120/100 too } return 60; } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index f0d69bc96..1799b5c6f 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -181,6 +181,14 @@ class FrameBufferSDL2 : public FrameBuffer */ bool setVideoMode(const string& title, const VideoMode& mode) override; + /** + Create a new renderer if required + + @param force If true, force new renderer creation + + @return False on any errors, else true + */ + bool createRenderer(bool force); /** Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode From 1a5f4aedc4d12af5d4dd8100d9d7c2cd2bfc674d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 19 May 2020 19:37:06 +0200 Subject: [PATCH 006/104] added avoiding switching refresh rate when going back to launcher improved error logging messages --- src/common/FrameBufferSDL2.cxx | 55 +++++++--------------------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index c977405fa..691e96510 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -220,24 +220,14 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) const bool fullScreen = mode.fsIndex != -1; const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") - && refreshRate() != gameRefreshRate(); + && gameRefreshRate() && refreshRate() != gameRefreshRate(); bool forceCreateRenderer = false; - // TODO: On multiple displays, switching from centered mode, does not respect - // current window's display (which many not be centered anymore) - // Get windowed window's last display Int32 displayIndex = std::min(myNumDisplays, myOSystem.settings().getInt(getDisplayKey())); // Get windowed window's last position myWindowedPos = myOSystem.settings().getPoint(getPositionKey()); - //// Always recreate renderer (some systems need this) - //if(myRenderer) - //{ - // SDL_DestroyRenderer(myRenderer); - // myRenderer = nullptr; - //} - int posX, posY; myCenter = myOSystem.settings().getBool("center"); @@ -282,7 +272,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) // as it's not necessary, and causes flashing in fullscreen mode if(myWindow) { - int d = SDL_GetWindowDisplayIndex(myWindow); + const int d = SDL_GetWindowDisplayIndex(myWindow); int w, h; SDL_GetWindowSize(myWindow, &w, &h); @@ -331,7 +321,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) // Switch to mode for adapted refresh rate if(SDL_SetWindowDisplayMode(myWindow, &adaptedSdlMode) != 0) { - Logger::error("Display refresh rate change failed"); + Logger::error("ERROR: Display refresh rate change failed"); } else { @@ -343,33 +333,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) } return createRenderer(forceCreateRenderer); - - //uInt32 renderFlags = SDL_RENDERER_ACCELERATED; - //if(myOSystem.settings().getBool("vsync") - // && !myOSystem.settings().getBool("turbo")) // V'synced blits option - // renderFlags |= SDL_RENDERER_PRESENTVSYNC; - //const string& video = myOSystem.settings().getString("video"); // Render hint - //if(video != "") - // SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); - - //myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags); - - //detectFeatures(); - //determineDimensions(); - - //if(myRenderer == nullptr) - //{ - // string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); - // Logger::error(msg); - // return false; - //} - //clear(); - - //SDL_RendererInfo renderinfo; - //if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) - // myOSystem.settings().setValue("video", renderinfo.name); - - //return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -396,7 +359,7 @@ bool FrameBufferSDL2::createRenderer(bool force) if(recreate) { - cerr << "Create new renderer " << int(myBufferType) << endl; + //cerr << "Create new renderer " << int(myBufferType) << endl; if(myRenderer) SDL_DestroyRenderer(myRenderer); @@ -418,6 +381,7 @@ bool FrameBufferSDL2::createRenderer(bool force) clear(); SDL_RendererInfo renderinfo; + if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0) myOSystem.settings().setValue("video", renderinfo.name); @@ -431,7 +395,7 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& clos if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) { - Logger::error("Display mode could not be retrieved"); + Logger::error("ERROR: Display mode could not be retrieved"); return false; } @@ -445,11 +409,12 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& clos // therefore the size will never change. if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == NULL) { - Logger::error("Closest display mode could not be retrieved"); + Logger::error("ERROR: Closest display mode could not be retrieved"); return false; } // Only change if the display supports a better refresh rate return currentRefreshRate != closestSdlMode.refresh_rate; + // TODO: check for multiples e.g. 120/100 too } return false; } @@ -538,9 +503,9 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 75 : 50; // TODO: check for multiples e.g. 120/100 too + return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too } - return 60; + return 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 842b40e5436b76a9604dee74e037e485f71e6d05 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 20 May 2020 10:19:31 +0200 Subject: [PATCH 007/104] added refresh rate adapt for integer factors of the game's refresh rate --- src/common/FrameBufferSDL2.cxx | 90 +++++++++++++++++++++------------- src/common/FrameBufferSDL2.hxx | 17 ++++--- 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 691e96510..72484c468 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -220,7 +220,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) const bool fullScreen = mode.fsIndex != -1; const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") - && gameRefreshRate() && refreshRate() != gameRefreshRate(); + && gameRefreshRate() && refreshRate() % gameRefreshRate() != 0; bool forceCreateRenderer = false; // Get windowed window's last display @@ -277,7 +277,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) SDL_GetWindowSize(myWindow, &w, &h); if(d != displayIndex || uInt32(w) != mode.screen.w || uInt32(h) != mode.screen.h - || shouldAdapt) + || adaptRefresh) { SDL_DestroyWindow(myWindow); myWindow = nullptr; @@ -335,6 +335,57 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) return createRenderer(forceCreateRenderer); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode) +{ + SDL_DisplayMode sdlMode; + + if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) + { + Logger::error("ERROR: Display mode could not be retrieved"); + return false; + } + + const int currentRefreshRate = sdlMode.refresh_rate; + const int wantedRefreshRate = gameRefreshRate(); + float factor = float(currentRefreshRate) / wantedRefreshRate; + float bestDiff = std::abs(factor - std::round(factor)) / factor; + bool adapt = false; + + // Display refresh rate should be an integer factor of the game's refresh rate + // Note: Modes are scanned with size being first priority, + // therefore the size will never change. + // Check for integer factors 1 (60/50 Hz) and 2 (120/100 Hz) + for(int m = 1; m <= 2; ++m) + { + SDL_DisplayMode closestSdlMode; + + sdlMode.refresh_rate = wantedRefreshRate * m; + if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == NULL) + { + Logger::error("ERROR: Closest display mode could not be retrieved"); + return adapt; + } + factor = float(closestSdlMode.refresh_rate) / sdlMode.refresh_rate; + const float diff = std::abs(factor - std::round(factor)) / factor; + if(diff < bestDiff) + { + bestDiff = diff; + adaptedSdlMode = closestSdlMode; + adapt = true; + } + } + cerr << "refresh rate adapt "; + if(adapt) + cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)"; + else + cerr << "not required/possible"; + cerr << endl; + + // Only change if the display supports a better refresh rate + return adapt; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::createRenderer(bool force) { @@ -359,7 +410,7 @@ bool FrameBufferSDL2::createRenderer(bool force) if(recreate) { - //cerr << "Create new renderer " << int(myBufferType) << endl; + cerr << "Create new renderer " << int(myBufferType) << endl; if(myRenderer) SDL_DestroyRenderer(myRenderer); @@ -388,37 +439,6 @@ bool FrameBufferSDL2::createRenderer(bool force) return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& closestSdlMode) -{ - SDL_DisplayMode sdlMode; - - if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) - { - Logger::error("ERROR: Display mode could not be retrieved"); - return false; - } - - const int currentRefreshRate = sdlMode.refresh_rate; - - sdlMode.refresh_rate = gameRefreshRate(); - - if(currentRefreshRate != sdlMode.refresh_rate) - { - // Note: Modes are scanned with size being first priority, - // therefore the size will never change. - if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == NULL) - { - Logger::error("ERROR: Closest display mode could not be retrieved"); - return false; - } - // Only change if the display supports a better refresh rate - return currentRefreshRate != closestSdlMode.refresh_rate; - // TODO: check for multiples e.g. 120/100 too - } - return false; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSDL2::setTitle(const string& title) { @@ -503,7 +523,7 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 60 : 50; // TODO: check for multiples e.g. 120/100 too + return isNtsc ? 60 : 50; } return 0; } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 1799b5c6f..08005f85a 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -181,6 +181,16 @@ class FrameBufferSDL2 : public FrameBuffer */ bool setVideoMode(const string& title, const VideoMode& mode) override; + /** + Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode + + @param displayIndex The display which should be checked + @adaptedSdlMode The best matching mode if the refresh rate should be changed + + @return True if the refresh rate should be changed + */ + bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode); + /** Create a new renderer if required @@ -190,13 +200,6 @@ class FrameBufferSDL2 : public FrameBuffer */ bool createRenderer(bool force); - /** - Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode - - @return True if the refresh rate should be changed - */ - bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& closestSdlMode); - /** This method is called to create a surface with the given attributes. From 294b4a44657f744b6a8256dc6fb93f73f02a9918 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Thu, 21 May 2020 23:00:23 +0200 Subject: [PATCH 008/104] Remove extra quote for audio presets The list of presets includes an extra quote in "low quality, medium lag"; this patch removes it. Signed-off-by: Stephen Kitt --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 3bf9ee26a..e5d859ba0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2155,7 +2155,7 @@
-audio.preset <1 - 5>
Set an audio preset. Numbers in sequence represent presets for - 'custom', 'low quality, 'medium lag', 'high quality, medium lag', + 'custom', 'low quality, medium lag', 'high quality, medium lag', 'high quality, low lag' and 'ultra quality, minimal lag'. From 0920518d29d601d81cc98bad4616b510357c9930 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 21 May 2020 22:15:13 -0230 Subject: [PATCH 009/104] Fix compilation in Xcode. --- src/common/FrameBufferSDL2.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 72484c468..0d5813168 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -15,6 +15,8 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include + #include "SDL_lib.hxx" #include "bspf.hxx" #include "Logger.hxx" From 9ea920524bf7de4f66ac11f4239f0c5cbaee7e45 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 22 May 2020 09:05:48 +0200 Subject: [PATCH 010/104] more compact available video modes logging --- src/common/FrameBufferSDL2.cxx | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 0d5813168..6070abbce 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -101,19 +101,32 @@ void FrameBufferSDL2::queryHardware(vector& fullscreenRes, int numModes = SDL_GetNumDisplayModes(i); ostringstream s; - s << "Supported video modes for display " << i << ":"; - Logger::debug(s.str()); + s << "Supported video modes (" << numModes << ") for display " << i << ":"; + + string lastRes = ""; + for (int m = 0; m < numModes; m++) { SDL_DisplayMode mode; + ostringstream res; SDL_GetDisplayMode(i, m, &mode); - s.str(""); - s << " " << m << ": " << mode.w << "x" << mode.h << "@" << mode.refresh_rate << "Hz"; - if (mode.w == display.w && mode.h == display.h && mode.refresh_rate == display.refresh_rate) - s << " (active)"; - Logger::debug(s.str()); + res << std::setw(4) << mode.w << "x" << std::setw(4) << mode.h; + + if(lastRes != res.str()) + { + Logger::debug(s.str()); + s.str(""); + lastRes = res.str(); + s << lastRes << ": "; + } + s << mode.refresh_rate << "Hz"; + if(mode.w == display.w && mode.h == display.h && mode.refresh_rate == display.refresh_rate) + s << "* "; + else + s << " "; } + Logger::debug(s.str()); } // Now get the maximum windowed desktop resolution @@ -329,7 +342,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) { ostringstream msg; - msg << "Display refresh rate changed to " << adaptedSdlMode.refresh_rate << "Hz"; + msg << "Display refresh rate changed to " << adaptedSdlMode.refresh_rate << " Hz"; Logger::info(msg.str()); } } @@ -412,7 +425,7 @@ bool FrameBufferSDL2::createRenderer(bool force) if(recreate) { - cerr << "Create new renderer " << int(myBufferType) << endl; + cerr << "Create new renderer for buffer type #" << int(myBufferType) << endl; if(myRenderer) SDL_DestroyRenderer(myRenderer); From f426f160a96e0d25801b04bac570df1cab084180 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 22 May 2020 15:07:20 -0230 Subject: [PATCH 011/104] Fix minor warnings from clang. --- src/common/FrameBufferSDL2.cxx | 6 ++++-- src/common/FrameBufferSDL2.hxx | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 6070abbce..a912b8ad3 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -376,7 +376,7 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap SDL_DisplayMode closestSdlMode; sdlMode.refresh_rate = wantedRefreshRate * m; - if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == NULL) + if(SDL_GetClosestDisplayMode(displayIndex, &sdlMode, &closestSdlMode) == nullptr) { Logger::error("ERROR: Closest display mode could not be retrieved"); return adapt; @@ -515,6 +515,7 @@ bool FrameBufferSDL2::fullScreen() const #endif } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int FrameBufferSDL2::refreshRate() const { ASSERT_MAIN_THREAD; @@ -525,8 +526,9 @@ int FrameBufferSDL2::refreshRate() const if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) == 0) return sdlMode.refresh_rate; - if (myWindow != NULL) + if(myWindow != nullptr) Logger::error("Could not retrieve current display mode"); + return 0; } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 08005f85a..7904ed0ee 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -184,8 +184,8 @@ class FrameBufferSDL2 : public FrameBuffer /** Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode - @param displayIndex The display which should be checked - @adaptedSdlMode The best matching mode if the refresh rate should be changed + @param displayIndex The display which should be checked + @param adaptedSdlMode The best matching mode if the refresh rate should be changed @return True if the refresh rate should be changed */ From de9277e98e4181dcf9f6d52ef85b5d326f96ea8c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 23 May 2020 12:29:31 +0200 Subject: [PATCH 012/104] handle rounded refresh rates like 59.94 Hz disable refresh adjust option for macOS --- src/common/FrameBufferSDL2.cxx | 91 ++++++++++++++++++++++++++++++++-- src/common/FrameBufferSDL2.hxx | 2 + src/gui/VideoAudioDialog.cxx | 10 ++++ src/gui/VideoAudioDialog.hxx | 2 + 4 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index a912b8ad3..9bb0dae57 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -234,8 +234,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) return false; const bool fullScreen = mode.fsIndex != -1; - const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") - && gameRefreshRate() && refreshRate() % gameRefreshRate() != 0; bool forceCreateRenderer = false; // Get windowed window's last display @@ -272,8 +270,17 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) posY = BSPF::clamp(posY, y0 + 50, y1 - 50); } +#ifndef BSPF_MACOS + // macOS does not allow to change the display refresh rate SDL_DisplayMode adaptedSdlMode; + const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") + && gameRefreshRate() + // take care of 59.94 Hz + && refreshRate() % gameRefreshRate() != 0 && refreshRate() % (gameRefreshRate() - 1) != 0; const bool adaptRefresh = shouldAdapt && adaptRefreshRate(displayIndex, adaptedSdlMode); +#else + const bool adaptRefresh = false; +#endif const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0); @@ -331,6 +338,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) setWindowIcon(); } +#ifndef BSPF_MACOS if(adaptRefresh) { // Switch to mode for adapted refresh rate @@ -346,10 +354,11 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) Logger::info(msg.str()); } } - +#endif return createRenderer(forceCreateRenderer); } +#ifndef BSPF_MACOS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode) { @@ -363,7 +372,10 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap const int currentRefreshRate = sdlMode.refresh_rate; const int wantedRefreshRate = gameRefreshRate(); - float factor = float(currentRefreshRate) / wantedRefreshRate; + // Take care of rounded refresh rates (e.g. 59.94 Hz) + float factor = std::min(float(currentRefreshRate) / wantedRefreshRate, + float(currentRefreshRate) / (wantedRefreshRate - 1)); + // Calculate difference taking care of integer factors (e.g. 100/120) float bestDiff = std::abs(factor - std::round(factor)) / factor; bool adapt = false; @@ -382,6 +394,8 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap return adapt; } factor = float(closestSdlMode.refresh_rate) / sdlMode.refresh_rate; + factor = std::min(float(sdlMode.refresh_rate) / sdlMode.refresh_rate, + float(sdlMode.refresh_rate) / (sdlMode.refresh_rate - 1)); const float diff = std::abs(factor - std::round(factor)) / factor; if(diff < bestDiff) { @@ -399,7 +413,74 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap // Only change if the display supports a better refresh rate return adapt; + +#if 0 + // Adapting resfresh rate and display size + const bool hiDpi = myOSystem.settings().getBool("hidpi"); + const float mult = float(font().getFontHeight()) / getFontDesc("medium").height * hiDpi ? 2 : 1; + const Int32 minWidth = FBMinimum::Width * mult; + const Int32 minHeight = FBMinimum::Height * mult; + SDL_DisplayMode sdlMode; + + if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) + { + Logger::error("ERROR: Display mode could not be retrieved"); + return false; + } + + const int numModes = SDL_GetNumDisplayModes(displayIndex); + if(numModes < 0) + { + Logger::error("ERROR: Number of display modes could not be retrieved"); + return false; + } + + const int currentRefreshRate = sdlMode.refresh_rate; + const int wantedRefreshRate = gameRefreshRate(); + // Take care of rounded refresh rates (e.g. 59.94) + float factor = std::min(float(currentRefreshRate) / wantedRefreshRate, + float(currentRefreshRate) / (wantedRefreshRate - 1)); + // Calculate difference taking care of integer factors (e.g. 100/120) + float bestDiff = std::abs(factor - std::round(factor)) / factor; + bool adapt = false; + + for(int mode = 0; mode < numModes; ++mode) + { + // Note: Display modes returned are sorted by width, height,... refresh_rate + if(SDL_GetDisplayMode(displayIndex, mode, &sdlMode) != 0) + { + Logger::error("ERROR: Display modes could not be retrieved"); + return false; + } + // skip too small modes + if(sdlMode.w < minWidth || sdlMode.h < minHeight) + continue; + + cerr << sdlMode.w << "x" << sdlMode.h << " " << sdlMode.refresh_rate << " Hz" << endl; + + factor = std::min(float(sdlMode.refresh_rate) / wantedRefreshRate, + float(sdlMode.refresh_rate) / (wantedRefreshRate - 1)); + const float diff = std::abs(factor - std::round(factor)) / factor; + if(diff < bestDiff) + { + bestDiff = diff; + adaptedSdlMode = sdlMode; + adapt = true; + } + } + + cerr << "refresh rate adapt "; + if(adapt) + cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)"; + else + cerr << "not required/possible"; + cerr << endl; + + // Only change if the display supports a better refresh rate + return adapt; +#endif } +#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::createRenderer(bool force) @@ -540,7 +621,7 @@ int FrameBufferSDL2::gameRefreshRate() const const string format = myOSystem.console().getFormatString(); const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60"; - return isNtsc ? 60 : 50; + return isNtsc ? 60 : 50; // The code will take care of 59/49 Hz } return 0; } diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 7904ed0ee..282cf2100 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -181,6 +181,7 @@ class FrameBufferSDL2 : public FrameBuffer */ bool setVideoMode(const string& title, const VideoMode& mode) override; + #ifndef BSPF_MACOS /** Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode @@ -190,6 +191,7 @@ class FrameBufferSDL2 : public FrameBuffer @return True if the refresh rate should be changed */ bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode); + #endif /** Create a new renderer if required diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 46203783a..edce71e10 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -153,10 +153,12 @@ void VideoAudioDialog::addDisplayTab() myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); wid.push_back(myUseStretch); +#ifndef BSPF_MACOS // Adapt refresh rate ypos += lineHeight + VGAP; myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); wid.push_back(myRefreshAdapt); +#endif // FS overscan ypos += lineHeight + VGAP; @@ -484,8 +486,10 @@ void VideoAudioDialog::loadConfig() myFullScreenMode->setSelected(mode);*/ // Fullscreen stretch setting myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); +#ifndef BSPF_MACOS // Adapt refresh rate myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh")); +#endif // Fullscreen overscan setting myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan")); handleFullScreenChange(); @@ -597,8 +601,10 @@ void VideoAudioDialog::saveConfig() instance().settings().setValue("fullscreen", myFullscreen->getState()); // Fullscreen stretch setting instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); +#ifndef BSPF_MACOS // Adapt refresh rate instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState()); +#endif // Fullscreen overscan instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel()); @@ -712,7 +718,9 @@ void VideoAudioDialog::setDefaults() myFullscreen->setState(false); //myFullScreenMode->setSelectedIndex(0); myUseStretch->setState(false); + #ifndef BSPF_MACOS myRefreshAdapt->setState(false); + #endif myTVOverscan->setValue(0); myTIAZoom->setValue(300); myVSizeAdjust->setValue(0); @@ -838,7 +846,9 @@ void VideoAudioDialog::handleFullScreenChange() { bool enable = myFullscreen->getState(); myUseStretch->setEnabled(enable); +#ifndef BSPF_MACOS myRefreshAdapt->setEnabled(enable); +#endif myTVOverscan->setEnabled(enable); } diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 0961f776e..c20b39438 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -73,7 +73,9 @@ class VideoAudioDialog : public Dialog CheckboxWidget* myFullscreen{nullptr}; CheckboxWidget* myUseStretch{nullptr}; SliderWidget* myTVOverscan{nullptr}; + #ifndef BSPF_MACOS CheckboxWidget* myRefreshAdapt{nullptr}; + #endif SliderWidget* myTIAZoom{nullptr}; SliderWidget* myVSizeAdjust{nullptr}; From c4aa9b2a56bacbd74bbd3a67ffcc243272ee997a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 23 May 2020 20:50:14 +0200 Subject: [PATCH 013/104] updated doc for fullscreen refresh rate adaption removed debug output --- Changes.txt | 2 ++ docs/graphics/options_video.png | Bin 2744 -> 3001 bytes docs/index.html | 15 +++++++++++---- src/common/FrameBufferSDL2.cxx | 15 +++++++-------- src/emucore/Settings.cxx | 2 +- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Changes.txt b/Changes.txt index 557157f25..616ec22f7 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,6 +37,8 @@ * Added separate positioning of launcher, emulator and debugger + * Added optional display to game refresh rate adaption in fullscreen mode + * Added option which lets default ROM path follow launcher navigation * Added debugger 'saveaccess' function, which saves memory access counts to diff --git a/docs/graphics/options_video.png b/docs/graphics/options_video.png index deb857ca4984e0d5815c693b739e4628a3b1b429..58654148ab3e6db654681c658c828eade4523b08 100644 GIT binary patch delta 2885 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 + +
-tia.fs_refresh <1|0>
+ While in fullscreen mode, adapt the display's refresh rate to the game's frame rate + to minimize judder. + +
-tia.fs_overscan <0 - 10>
Add overscan to TIA image while in fullscreen mode @@ -2943,13 +2949,14 @@ - - + + - + + - +
ItemBrief descriptionFor more information,
see CommandLine
RendererUse specified rendering mode-video
InterpolationInterpolation of TIA image-tia.inter
ZoomZoom level of TIA image-tia.zoom
InterpolationEnable interpolation of the TIA image-tia.inter
ZoomZoom level of the TIA image-tia.zoom
FullscreenSelf-explanatory - Note that colors may slightly change. This depends on the OS and renderer used.-fullscreen
StretchIn fullscreen mode, completely fill screen with TIA image-tia.fs_stretch
StretchIn fullscreen mode, completely fill screen with the TIA image.-tia.fs_stretch
Adapt display...In fullscreen mode, adapt the display's refresh rate to the game's frame rate to minimize judder.-tia.fs_refresh
OverscanIn fullscreen mode, add overscan to the TIA image-tia.fs_overscan
V-Size adjustAdjust height of TIA image-tia.vsizeadjust
V-Size adjustAdjust height of the TIA image-tia.vsizeadjust
diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 9bb0dae57..612000943 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -393,7 +393,6 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap Logger::error("ERROR: Closest display mode could not be retrieved"); return adapt; } - factor = float(closestSdlMode.refresh_rate) / sdlMode.refresh_rate; factor = std::min(float(sdlMode.refresh_rate) / sdlMode.refresh_rate, float(sdlMode.refresh_rate) / (sdlMode.refresh_rate - 1)); const float diff = std::abs(factor - std::round(factor)) / factor; @@ -404,12 +403,12 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap adapt = true; } } - cerr << "refresh rate adapt "; - if(adapt) - cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)"; - else - cerr << "not required/possible"; - cerr << endl; + //cerr << "refresh rate adapt "; + //if(adapt) + // cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)"; + //else + // cerr << "not required/possible"; + //cerr << endl; // Only change if the display supports a better refresh rate return adapt; @@ -506,7 +505,7 @@ bool FrameBufferSDL2::createRenderer(bool force) if(recreate) { - cerr << "Create new renderer for buffer type #" << int(myBufferType) << endl; + //cerr << "Create new renderer for buffer type #" << int(myBufferType) << endl; if(myRenderer) SDL_DestroyRenderer(myRenderer); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index dca79717d..790c784bb 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -442,7 +442,7 @@ void Settings::usage() const << " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA\n" << " image\n" << " -tia.fs_stretch <1|0> Stretch TIA image to fill fullscreen mode\n" - << " -tia.fs_refresh <1|0> Try to adapt display refresh rate to game\n" + << " -tia.fs_refresh <1|0> Try to adapt display refresh rate to game's FPS\n" << " -tia.fs_overscan <0-10> Add overscan to TIA image in fullscreen mode\n" << " -tia.dbgcolors Debug colors to use for each object (see manual\n" << " for description)\n" From ac9143ef08ace05655f08769e0f432cfdafef305 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 23 May 2020 17:15:42 -0230 Subject: [PATCH 014/104] Add 'ADAPTABLE_REFRESH_SUPPORT', and enable it on non-Mac systems. Cleaned up some dead code. Made MacOS toggle from windowed to fullscreen work the same as all other systems. --- src/common/FrameBufferSDL2.cxx | 96 ++-------------------------------- src/common/FrameBufferSDL2.hxx | 2 - src/common/bspf.hxx | 6 +++ src/gui/VideoAudioDialog.cxx | 24 +++------ src/gui/VideoAudioDialog.hxx | 2 - 5 files changed, 18 insertions(+), 112 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 612000943..d930b2fc0 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -270,8 +270,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) posY = BSPF::clamp(posY, y0 + 50, y1 - 50); } -#ifndef BSPF_MACOS - // macOS does not allow to change the display refresh rate +#ifdef ADAPTABLE_REFRESH_SUPPORT SDL_DisplayMode adaptedSdlMode; const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh") && gameRefreshRate() @@ -284,12 +283,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - // macOS seems to have issues with destroying the window, and wants to - // keep the same handle - // Problem is, doing so on other platforms results in flickering when - // toggling fullscreen windowed mode - // So we have a special case for macOS -#ifndef BSPF_MACOS // Don't re-create the window if its display and size hasn't changed, // as it's not necessary, and causes flashing in fullscreen mode if(myWindow) @@ -312,18 +305,6 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) SDL_SetWindowTitle(myWindow, title.c_str()); SDL_SetWindowPosition(myWindow, posX, posY); } -#else - // macOS wants to *never* re-create the window - // This sometimes results in the window being resized *after* it's displayed, - // but at least the code works and doesn't crash - if(myWindow) - { - SDL_SetWindowFullscreen(myWindow, flags); - SDL_SetWindowSize(myWindow, mode.screen.w, mode.screen.h); - SDL_SetWindowPosition(myWindow, posX, posY); - SDL_SetWindowTitle(myWindow, title.c_str()); - } -#endif else { forceCreateRenderer = true; @@ -338,7 +319,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) setWindowIcon(); } -#ifndef BSPF_MACOS + +#ifdef ADAPTABLE_REFRESH_SUPPORT if(adaptRefresh) { // Switch to mode for adapted refresh rate @@ -355,10 +337,10 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) } } #endif + return createRenderer(forceCreateRenderer); } -#ifndef BSPF_MACOS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode) { @@ -412,74 +394,7 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap // Only change if the display supports a better refresh rate return adapt; - -#if 0 - // Adapting resfresh rate and display size - const bool hiDpi = myOSystem.settings().getBool("hidpi"); - const float mult = float(font().getFontHeight()) / getFontDesc("medium").height * hiDpi ? 2 : 1; - const Int32 minWidth = FBMinimum::Width * mult; - const Int32 minHeight = FBMinimum::Height * mult; - SDL_DisplayMode sdlMode; - - if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0) - { - Logger::error("ERROR: Display mode could not be retrieved"); - return false; - } - - const int numModes = SDL_GetNumDisplayModes(displayIndex); - if(numModes < 0) - { - Logger::error("ERROR: Number of display modes could not be retrieved"); - return false; - } - - const int currentRefreshRate = sdlMode.refresh_rate; - const int wantedRefreshRate = gameRefreshRate(); - // Take care of rounded refresh rates (e.g. 59.94) - float factor = std::min(float(currentRefreshRate) / wantedRefreshRate, - float(currentRefreshRate) / (wantedRefreshRate - 1)); - // Calculate difference taking care of integer factors (e.g. 100/120) - float bestDiff = std::abs(factor - std::round(factor)) / factor; - bool adapt = false; - - for(int mode = 0; mode < numModes; ++mode) - { - // Note: Display modes returned are sorted by width, height,... refresh_rate - if(SDL_GetDisplayMode(displayIndex, mode, &sdlMode) != 0) - { - Logger::error("ERROR: Display modes could not be retrieved"); - return false; - } - // skip too small modes - if(sdlMode.w < minWidth || sdlMode.h < minHeight) - continue; - - cerr << sdlMode.w << "x" << sdlMode.h << " " << sdlMode.refresh_rate << " Hz" << endl; - - factor = std::min(float(sdlMode.refresh_rate) / wantedRefreshRate, - float(sdlMode.refresh_rate) / (wantedRefreshRate - 1)); - const float diff = std::abs(factor - std::round(factor)) / factor; - if(diff < bestDiff) - { - bestDiff = diff; - adaptedSdlMode = sdlMode; - adapt = true; - } - } - - cerr << "refresh rate adapt "; - if(adapt) - cerr << "required (" << currentRefreshRate << " Hz -> " << adaptedSdlMode.refresh_rate << " Hz)"; - else - cerr << "not required/possible"; - cerr << endl; - - // Only change if the display supports a better refresh rate - return adapt; -#endif } -#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSDL2::createRenderer(bool force) @@ -637,10 +552,9 @@ void FrameBufferSDL2::renderToScreen() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSDL2::setWindowIcon() { - ASSERT_MAIN_THREAD; - #if !defined(BSPF_MACOS) && !defined(RETRON77) #include "stella_icon.hxx" + ASSERT_MAIN_THREAD; SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(stella_icon, 32, 32, 32, 32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 282cf2100..7904ed0ee 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -181,7 +181,6 @@ class FrameBufferSDL2 : public FrameBuffer */ bool setVideoMode(const string& title, const VideoMode& mode) override; - #ifndef BSPF_MACOS /** Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode @@ -191,7 +190,6 @@ class FrameBufferSDL2 : public FrameBuffer @return True if the refresh rate should be changed */ bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode); - #endif /** Create a new renderer if required diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index f21a99a4c..3fc1aaf6c 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -101,6 +101,12 @@ static const string EmptyString(""); #undef PAGE_SIZE #undef PAGE_MASK +// Adaptable refresh is currently not available on MacOS +// In the future, this may expand to other systems +#if !defined(BSPF_MACOS) + #define ADAPTABLE_REFRESH_SUPPORT +#endif + namespace BSPF { static constexpr float PI_f = 3.141592653589793238462643383279502884F; diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index edce71e10..c51685fcf 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -83,14 +83,6 @@ VideoAudioDialog::VideoAudioDialog(OSystem& osystem, DialogContainer& parent, addTVEffectsTab(); addAudioTab(); - //const int req_w = std::max(myFastSCBios->getRight(), myCloneBad->getRight()) + HBORDER + 1; - //const int req_h = _th + VGAP * 3 - // + std::max(myUseVSync->getBottom(), myTVScanIntense->getBottom()) - // + buttonHeight + VBORDER * 2; - //// Set real dimensions - //setSize(req_w, req_h, max_w, max_h); - - // Add Defaults, OK and Cancel buttons WidgetArray wid; addDefaultsOKCancelBGroup(wid, _font); @@ -153,11 +145,13 @@ void VideoAudioDialog::addDisplayTab() myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); wid.push_back(myUseStretch); -#ifndef BSPF_MACOS +#ifdef ADAPTABLE_REFRESH_SUPPORT // Adapt refresh rate ypos += lineHeight + VGAP; myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); wid.push_back(myRefreshAdapt); +#else + myRefreshAdapt = nullptr; #endif // FS overscan @@ -482,11 +476,9 @@ void VideoAudioDialog::loadConfig() // Fullscreen myFullscreen->setState(instance().settings().getBool("fullscreen")); - /*string mode = instance().settings().getString("fullscreenmode"); - myFullScreenMode->setSelected(mode);*/ // Fullscreen stretch setting myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); -#ifndef BSPF_MACOS +#ifdef ADAPTABLE_REFRESH_SUPPORT // Adapt refresh rate myRefreshAdapt->setState(instance().settings().getBool("tia.fs_refresh")); #endif @@ -601,7 +593,7 @@ void VideoAudioDialog::saveConfig() instance().settings().setValue("fullscreen", myFullscreen->getState()); // Fullscreen stretch setting instance().settings().setValue("tia.fs_stretch", myUseStretch->getState()); -#ifndef BSPF_MACOS +#ifdef ADAPTABLE_REFRESH_SUPPORT // Adapt refresh rate instance().settings().setValue("tia.fs_refresh", myRefreshAdapt->getState()); #endif @@ -621,7 +613,6 @@ void VideoAudioDialog::saveConfig() // Note: Palette values are saved directly when changed! - ///////////////////////////////////////////////////////////////////////////// // TV Effects tab // TV Mode @@ -716,9 +707,8 @@ void VideoAudioDialog::setDefaults() myTIAInterpolate->setState(false); // screen size myFullscreen->setState(false); - //myFullScreenMode->setSelectedIndex(0); myUseStretch->setState(false); - #ifndef BSPF_MACOS + #ifdef ADAPTABLE_REFRESH_SUPPORT myRefreshAdapt->setState(false); #endif myTVOverscan->setValue(0); @@ -846,7 +836,7 @@ void VideoAudioDialog::handleFullScreenChange() { bool enable = myFullscreen->getState(); myUseStretch->setEnabled(enable); -#ifndef BSPF_MACOS +#ifdef ADAPTABLE_REFRESH_SUPPORT myRefreshAdapt->setEnabled(enable); #endif myTVOverscan->setEnabled(enable); diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index c20b39438..0961f776e 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -73,9 +73,7 @@ class VideoAudioDialog : public Dialog CheckboxWidget* myFullscreen{nullptr}; CheckboxWidget* myUseStretch{nullptr}; SliderWidget* myTVOverscan{nullptr}; - #ifndef BSPF_MACOS CheckboxWidget* myRefreshAdapt{nullptr}; - #endif SliderWidget* myTIAZoom{nullptr}; SliderWidget* myVSizeAdjust{nullptr}; From 449bfb38d95ac79710bd8d226b882f5ac820bdf1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 24 May 2020 10:03:53 +0200 Subject: [PATCH 015/104] updated doc (adapting refresh not available for macOS) added event and hotkey for adapting refresh rate fixed endless loop in global hotkeys --- docs/index.html | 15 ++++++++++--- src/common/PKeyboardHandler.cxx | 1 + src/emucore/Event.hxx | 1 + src/emucore/EventHandler.cxx | 37 +++++++++++++++++++++++++++------ src/emucore/EventHandler.hxx | 10 ++++++++- src/emucore/FrameBuffer.cxx | 29 ++++++++++++++++++++++++++ src/emucore/FrameBuffer.hxx | 7 +++++++ 7 files changed, 90 insertions(+), 10 deletions(-) diff --git a/docs/index.html b/docs/index.html index 85ddf5b74..d97a89022 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1377,6 +1377,13 @@ Alt + Enter Cmd + Enter + + Toggle adapting display refresh rate to game frame rate +
+ Note: Not available for macOS. + Alt + r + Cmd + r + Decrease overscan in fullscreen mode Shift + PageDown @@ -2191,7 +2198,7 @@
-audio.dpc_pitch <10000 - 30000>
- Set the pitch o f Pitfall II music. + Set the pitch of Pitfall II music. @@ -2221,7 +2228,8 @@
-tia.fs_refresh <1|0>
While in fullscreen mode, adapt the display's refresh rate to the game's frame rate - to minimize judder. + to minimize judder.
+ Note: Not available for macOS. @@ -2954,7 +2962,8 @@ FullscreenSelf-explanatory - Note that colors may slightly change. This depends on the OS and renderer used.-fullscreen StretchIn fullscreen mode, completely fill screen with the TIA image.-tia.fs_stretch - Adapt display...In fullscreen mode, adapt the display's refresh rate to the game's frame rate to minimize judder.-tia.fs_refresh + Adapt display...In fullscreen mode, adapt the display's refresh rate to the game's frame rate to minimize judder. +
Note: Not available for macOS.-tia.fs_refresh OverscanIn fullscreen mode, add overscan to the TIA image-tia.fs_overscan V-Size adjustAdjust height of the TIA image-tia.vsizeadjust diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index cf4a31831..81b25cd6e 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -467,6 +467,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::SoundToggle, KBDK_RIGHTBRACKET, KBDM_CTRL}, {Event::ToggleFullScreen, KBDK_RETURN, MOD3}, + {Event::ToggleAdaptRefresh, KBDK_R, MOD3}, {Event::OverscanDecrease, KBDK_PAGEDOWN, KBDM_SHIFT}, {Event::OverscanIncrease, KBDK_PAGEUP, KBDM_SHIFT}, //{Event::VidmodeStd, KBDK_1, MOD3}, diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index fa8a4d04d..ddac653f3 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -123,6 +123,7 @@ class Event ToggleFrameStats, ToggleSAPortOrder, ExitGame, // add new events from here to avoid that user remapped events get overwritten SettingDecrease, SettingIncrease, PreviousSetting, NextSetting, + ToggleAdaptRefresh, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index fa87be91d..3817232c6 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -350,17 +350,25 @@ AdjustFunction EventHandler::cycleAdjustSetting(int direction) myOSystem.settings().getString("palette") == PaletteHandler::SETTING_CUSTOM; const bool isCustomFilter = myOSystem.settings().getInt("tv.filter") == int(NTSCFilter::Preset::CUSTOM); + bool repeat; do { myAdjustSetting = AdjustSetting(BSPF::clampw(int(myAdjustSetting) + direction, 0, int(AdjustSetting::MAX_ADJ))); // skip currently non-relevant adjustments - } while((myAdjustSetting == AdjustSetting::OVERSCAN && !isFullScreen) - || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette) - || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS - && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING - && !isCustomFilter)); + repeat = (myAdjustSetting == AdjustSetting::OVERSCAN && !isFullScreen) + #ifdef ADAPTABLE_REFRESH_SUPPORT + || (myAdjustSetting == AdjustSetting::ADAPT_REFRESH && !isFullScreen) + #endif + || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette) + || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS + && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING + && !isCustomFilter); + // avoid endless loop + if(repeat && !direction) + direction = 1; + } while(repeat); return getAdjustSetting(myAdjustSetting); } @@ -376,6 +384,9 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&Sound::adjustVolume, &myOSystem.sound(), _1), std::bind(&FrameBuffer::selectVidMode, &myOSystem.frameBuffer(), _1), std::bind(&FrameBuffer::toggleFullscreen, &myOSystem.frameBuffer(), _1), + #ifdef ADAPTABLE_REFRESH_SUPPORT + std::bind(&FrameBuffer::toggleAdaptRefresh, &myOSystem.frameBuffer(), _1), + #endif std::bind(&FrameBuffer::changeOverscan, &myOSystem.frameBuffer(), _1), std::bind(&Console::selectFormat, &myOSystem.console(), _1), std::bind(&Console::changeVerticalCenter, &myOSystem.console(), _1), @@ -658,6 +669,17 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; + #ifdef ADAPTABLE_REFRESH_SUPPORT + case Event::ToggleAdaptRefresh: + if(pressed && !repeated) + { + myOSystem.frameBuffer().toggleAdaptRefresh(); + myAdjustSetting = AdjustSetting::ADAPT_REFRESH; + myAdjustActive = true; + } + return; + #endif + case Event::OverscanDecrease: if(pressed) { @@ -2218,6 +2240,9 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::KeyboardOnePound, "P1 Keyboard #", "" }, // Video { Event::ToggleFullScreen, "Toggle fullscreen", "" }, +#ifdef ADAPTABLE_REFRESH_SUPPORT + { Event::ToggleAdaptRefresh, "Toggle fullscreen refresh rate adapt", "" }, +#endif { Event::OverscanDecrease, "Decrease overscan in fullscreen mode", "" }, { Event::OverscanIncrease, "Increase overscan in fullscreen mode", "" }, { Event::VidmodeDecrease, "Previous zoom level", "" }, @@ -2361,7 +2386,7 @@ const Event::EventSet EventHandler::MiscEvents = { const Event::EventSet EventHandler::AudioVideoEvents = { Event::VolumeDecrease, Event::VolumeIncrease, Event::SoundToggle, Event::VidmodeDecrease, Event::VidmodeIncrease, - Event::ToggleFullScreen, + Event::ToggleFullScreen, Event::ToggleAdaptRefresh, Event::OverscanDecrease, Event::OverscanIncrease, Event::FormatDecrease, Event::FormatIncrease, Event::VCenterDecrease, Event::VCenterIncrease, diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 0ab40c7cd..7d9dd235e 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -398,6 +398,9 @@ class EventHandler VOLUME, ZOOM, FULLSCREEN, + #ifdef ADAPTABLE_REFRESH_SUPPORT + ADAPT_REFRESH, + #endif OVERSCAN, TVFORMAT, VCENTER, @@ -517,7 +520,12 @@ class EventHandler #else PNG_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 156 + PNG_SIZE + COMBO_SIZE, + #ifdef ADAPTABLE_REFRESH_SUPPORT + REFRESH_SIZE = 1, + #else + REFRESH_SIZE = 0, + #endif + EMUL_ACTIONLIST_SIZE = 156 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 88f62517f..4812e22f6 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -1008,6 +1008,35 @@ void FrameBuffer::toggleFullscreen(bool toggle) } } +#ifdef ADAPTABLE_REFRESH_SUPPORT +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::toggleAdaptRefresh(bool toggle) +{ + bool isAdaptRefresh = myOSystem.settings().getInt("tia.fs_refresh"); + + if(toggle) + isAdaptRefresh = !isAdaptRefresh; + + if(myBufferType == BufferType::Emulator) + { + if(toggle) + { + myOSystem.settings().setValue("tia.fs_refresh", isAdaptRefresh); + // issue a complete framebuffer re-initialization + myOSystem.createFrameBuffer(); + } + + ostringstream msg; + + msg << "Adapt refresh rate "; + msg << (isAdaptRefresh ? "enabled" : "disabled"); + msg << " (" << refreshRate() << " Hz)"; + + showMessage(msg.str()); + } +} +#endif + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::changeOverscan(int direction) { diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 945cbb780..a86743911 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -269,6 +269,13 @@ class FrameBuffer */ void toggleFullscreen(bool toggle = true); + #ifdef ADAPTABLE_REFRESH_SUPPORT + /** + Toggles between adapt fullscreen refresh rate on and off. + */ + void FrameBuffer::toggleAdaptRefresh(bool toggle = true); + #endif + /** Changes the fullscreen overscan. From 894ab903ac5f02f1ac3748fe35feaa71ccbffa98 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 13:10:59 -0230 Subject: [PATCH 016/104] Fix compile error. --- src/emucore/FrameBuffer.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index a86743911..b09d492f1 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -273,7 +273,7 @@ class FrameBuffer /** Toggles between adapt fullscreen refresh rate on and off. */ - void FrameBuffer::toggleAdaptRefresh(bool toggle = true); + void toggleAdaptRefresh(bool toggle = true); #endif /** From 26887e314ee93b8acc7478b6f87665bd21ec4a17 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 16:08:24 -0230 Subject: [PATCH 017/104] Shorten error messages in ROM launcher, to fix overflow of buffer width. --- src/emucore/OSystem.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 9c84b4165..2bb3746d4 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -414,7 +414,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, } catch(const runtime_error& e) { - buf << "ERROR: Couldn't create console (" << e.what() << ")"; + buf << "ERROR: " << e.what(); Logger::error(buf.str()); return buf.str(); } From c41c0cf805bf330361e2c3ae8bdf87b4aaf8d493 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 18:57:45 -0230 Subject: [PATCH 018/104] Unify Cartridge::bank() and CartEnhanced::bank(). Otherwise, gcc complains of methods mirroring another with the same name. --- src/emucore/Cart.hxx | 8 ++++++-- src/emucore/CartAR.cxx | 2 +- src/emucore/CartAR.hxx | 7 +++++-- src/emucore/CartBUS.cxx | 2 +- src/emucore/CartBUS.hxx | 7 +++++-- src/emucore/CartCDF.cxx | 2 +- src/emucore/CartCDF.hxx | 7 +++++-- src/emucore/CartCM.cxx | 2 +- src/emucore/CartCM.hxx | 7 +++++-- src/emucore/CartCTY.cxx | 2 +- src/emucore/CartCTY.hxx | 7 +++++-- src/emucore/CartDPCPlus.cxx | 2 +- src/emucore/CartDPCPlus.hxx | 7 +++++-- src/emucore/CartEnhanced.hxx | 11 +---------- src/emucore/CartMDM.cxx | 2 +- src/emucore/CartMDM.hxx | 7 +++++-- src/emucore/CartMNetwork.cxx | 2 +- src/emucore/CartMNetwork.hxx | 7 +++++-- 18 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index b04a95f10..cfd19497c 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -169,8 +169,13 @@ class Cartridge : public Device scheme defines banks in a standard format (ie, 0 for first bank, 1 for second, etc). Carts which will handle their own bankswitching completely or non-bankswitched carts can ignore this method. + + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - virtual bool bank(uInt16) { return false; } + virtual bool bank(uInt16 bank, uInt16 segment = 0) { return false; } /** Get the current bank for the provided address. Carts which have only @@ -197,7 +202,6 @@ class Cartridge : public Device */ virtual uInt16 romBankCount() const { return 1; } - /** Query the number of RAM 'banks' supported by the cartridge. Note that this information is cart-specific, where each cart basically defines diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index a0eea7486..08f803e0b 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -392,7 +392,7 @@ void CartridgeAR::loadIntoRAM(uInt8 load) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeAR::bank(uInt16 bank) +bool CartridgeAR::bank(uInt16 bank, uInt16) { if(!bankLocked()) return bankConfiguration(uInt8(bank)); diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 0bc74a291..349de38f1 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -73,9 +73,12 @@ class CartridgeAR : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index e2eb9b74a..62000118b 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -429,7 +429,7 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBUS::bank(uInt16 bank) +bool CartridgeBUS::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 3ab40f7ec..58e4eea48 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -84,9 +84,12 @@ class CartridgeBUS : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 6f9a5f4f7..09e0da3e3 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -402,7 +402,7 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCDF::bank(uInt16 bank) +bool CartridgeCDF::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 14b1eda26..62c1721ca 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -90,9 +90,12 @@ class CartridgeCDF : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index 40ec603e5..b5dfc5197 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -98,7 +98,7 @@ uInt8 CartridgeCM::column() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCM::bank(uInt16 bank) +bool CartridgeCM::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index bf8b2586e..36fa13fa8 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -141,9 +141,12 @@ class CartridgeCM : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index 822473081..dbb5d13e2 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -229,7 +229,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCTY::bank(uInt16 bank) +bool CartridgeCTY::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index fdd6c1e19..1cd682446 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -139,9 +139,12 @@ class CartridgeCTY : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index b71f5a8c0..7a0a7f4c6 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -591,7 +591,7 @@ bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDPCPlus::bank(uInt16 bank) +bool CartridgeDPCPlus::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 9617d6545..bbbf68197 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -86,9 +86,12 @@ class CartridgeDPCPlus : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 743a4b50e..3c2e2c80d 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -70,16 +70,7 @@ class CartridgeEnhanced : public Cartridge @return true, if bank has changed */ - virtual bool bank(uInt16 bank, uInt16 segment); - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - - @return true, if bank has changed - */ - bool bank(uInt16 bank) override { return this->bank(bank, 0); } + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index decb634ec..2734b2793 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -88,7 +88,7 @@ bool CartridgeMDM::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMDM::bank(uInt16 bank) +bool CartridgeMDM::bank(uInt16 bank, uInt16) { if(bankLocked() || myBankingDisabled) return false; diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index 4b0786e42..fe17ae628 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -73,9 +73,12 @@ class CartridgeMDM : public CartridgeEnhanced /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index c6542b2b8..84cf8dac8 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -201,7 +201,7 @@ void CartridgeMNetwork::bankRAM(uInt16 bank) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMNetwork::bank(uInt16 bank) +bool CartridgeMNetwork::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index 95cd24b56..7b4fdb729 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -94,9 +94,12 @@ class CartridgeMNetwork : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. From cb847c94b1e635b9b49243a9282edd5de854caf7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 24 May 2020 23:45:46 +0200 Subject: [PATCH 019/104] Revert "Merge branch 'master' of https://github.com/stella-emu/stella" This reverts commit 3f9ef8026b1b8e8a44b7ce0d17f54f5540f26fc6, reversing changes made to 191684b6d2cf906904cf4573c5dd30fce8404873. --- src/emucore/Bankswitch.cxx | 4 +++ src/emucore/Bankswitch.hxx | 16 ++++++------ src/emucore/Cart.hxx | 8 ++---- src/emucore/CartAR.cxx | 2 +- src/emucore/CartAR.hxx | 7 ++--- src/emucore/CartBUS.cxx | 2 +- src/emucore/CartBUS.hxx | 7 ++--- src/emucore/CartCDF.cxx | 2 +- src/emucore/CartCDF.hxx | 7 ++--- src/emucore/CartCM.cxx | 2 +- src/emucore/CartCM.hxx | 7 ++--- src/emucore/CartCTY.cxx | 2 +- src/emucore/CartCTY.hxx | 7 ++--- src/emucore/CartDPCPlus.cxx | 2 +- src/emucore/CartDPCPlus.hxx | 7 ++--- src/emucore/CartDetector.cxx | 16 ++++++++++++ src/emucore/CartDetector.hxx | 5 ++++ src/emucore/CartEnhanced.hxx | 11 +++++++- src/emucore/CartMDM.cxx | 2 +- src/emucore/CartMDM.hxx | 7 ++--- src/emucore/CartMNetwork.cxx | 2 +- src/emucore/CartMNetwork.hxx | 7 ++--- src/emucore/EventHandler.cxx | 42 +++++++++++++++++++++++++----- src/emucore/OSystem.cxx | 2 +- src/windows/Stella.vcxproj | 4 +++ src/windows/Stella.vcxproj.filters | 12 +++++++++ 26 files changed, 122 insertions(+), 70 deletions(-) diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index 1b907eea7..2ea053df1 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -141,6 +141,7 @@ Bankswitch::BSList = {{ { "FE" , "FE (8K Decathlon)" }, { "MDM" , "MDM (Menu Driven Megacart)" }, { "SB" , "SB (128-256K SUPERbank)" }, + { "TVBOY" , "TV Boy (512K)" }, { "UA" , "UA (8K UA Ltd.)" }, { "UASW" , "UASW (8K UA swapped banks)" }, { "WD" , "WD (Pink Panther)" }, @@ -226,6 +227,8 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = { { "FE" , Bankswitch::Type::_FE }, { "MDM" , Bankswitch::Type::_MDM }, { "SB" , Bankswitch::Type::_SB }, + { "TVB" , Bankswitch::Type::_TVBOY }, + { "TVBOY" , Bankswitch::Type::_TVBOY }, { "UA" , Bankswitch::Type::_UA }, { "UASW" , Bankswitch::Type::_UASW }, { "WD" , Bankswitch::Type::_WD }, @@ -282,6 +285,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = { { "FE" , Bankswitch::Type::_FE }, { "MDM" , Bankswitch::Type::_MDM }, { "SB" , Bankswitch::Type::_SB }, + { "TVBOY" , Bankswitch::Type::_TVBOY }, { "UA" , Bankswitch::Type::_UA }, { "UASW" , Bankswitch::Type::_UASW }, { "WD" , Bankswitch::Type::_WD }, diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx index 0dd3871c7..6ef5da867 100644 --- a/src/emucore/Bankswitch.hxx +++ b/src/emucore/Bankswitch.hxx @@ -38,14 +38,14 @@ class Bankswitch public: // Currently supported bankswitch schemes enum class Type { - _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, - _64IN1, _128IN1, _2K, _3E, _3EX, _3EP, _3F, - _4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS, - _CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC, - _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0, - _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, - _FA2, _FC, _FE, _MDM, _SB, _UA, _UASW, - _WD, _WDSW, _X07, + _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, + _64IN1, _128IN1, _2K, _3E, _3EX, _3EP, _3F, + _4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS, + _CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC, + _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0, + _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, + _FA2, _FC, _FE, _MDM, _SB, _TVBOY, _UA, + _UASW, _WD, _WDSW, _X07, #ifdef CUSTOM_ARM _CUSTOM, #endif diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index cfd19497c..b04a95f10 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -169,13 +169,8 @@ class Cartridge : public Device scheme defines banks in a standard format (ie, 0 for first bank, 1 for second, etc). Carts which will handle their own bankswitching completely or non-bankswitched carts can ignore this method. - - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed */ - virtual bool bank(uInt16 bank, uInt16 segment = 0) { return false; } + virtual bool bank(uInt16) { return false; } /** Get the current bank for the provided address. Carts which have only @@ -202,6 +197,7 @@ class Cartridge : public Device */ virtual uInt16 romBankCount() const { return 1; } + /** Query the number of RAM 'banks' supported by the cartridge. Note that this information is cart-specific, where each cart basically defines diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index 08f803e0b..a0eea7486 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -392,7 +392,7 @@ void CartridgeAR::loadIntoRAM(uInt8 load) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeAR::bank(uInt16 bank, uInt16) +bool CartridgeAR::bank(uInt16 bank) { if(!bankLocked()) return bankConfiguration(uInt8(bank)); diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 349de38f1..0bc74a291 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -73,12 +73,9 @@ class CartridgeAR : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index 62000118b..e2eb9b74a 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -429,7 +429,7 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBUS::bank(uInt16 bank, uInt16) +bool CartridgeBUS::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 58e4eea48..3ab40f7ec 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -84,12 +84,9 @@ class CartridgeBUS : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 09e0da3e3..6f9a5f4f7 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -402,7 +402,7 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCDF::bank(uInt16 bank, uInt16) +bool CartridgeCDF::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 62c1721ca..14b1eda26 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -90,12 +90,9 @@ class CartridgeCDF : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index b5dfc5197..40ec603e5 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -98,7 +98,7 @@ uInt8 CartridgeCM::column() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCM::bank(uInt16 bank, uInt16) +bool CartridgeCM::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index 36fa13fa8..bf8b2586e 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -141,12 +141,9 @@ class CartridgeCM : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index dbb5d13e2..822473081 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -229,7 +229,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCTY::bank(uInt16 bank, uInt16) +bool CartridgeCTY::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index 1cd682446..fdd6c1e19 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -139,12 +139,9 @@ class CartridgeCTY : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 7a0a7f4c6..b71f5a8c0 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -591,7 +591,7 @@ bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDPCPlus::bank(uInt16 bank, uInt16) +bool CartridgeDPCPlus::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index bbbf68197..9617d6545 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -86,12 +86,9 @@ class CartridgeDPCPlus : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 976d56579..2ff85803d 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -56,6 +56,7 @@ #include "CartFE.hxx" #include "CartMDM.hxx" #include "CartSB.hxx" +#include "CartTVBoy.hxx" #include "CartUA.hxx" #include "CartWD.hxx" #include "CartX07.hxx" @@ -328,6 +329,8 @@ CartDetector::createFromImage(const ByteBuffer& image, size_t size, Bankswitch:: return make_unique(image, size, md5, settings, true); case Bankswitch::Type::_SB: return make_unique(image, size, md5, settings); + case Bankswitch::Type::_TVBOY: + return make_unique(image, size, md5, settings); case Bankswitch::Type::_WD: case Bankswitch::Type::_WDSW: return make_unique(image, size, md5, settings); @@ -524,6 +527,11 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si else /*if(isProbablySB(image, size))*/ type = Bankswitch::Type::_SB; } + else if(size == 512_KB) + { + if(isProbablyTVBoy(image, size)) + type = Bankswitch::Type::_TVBOY; + } else // what else can we do? { if(isProbably3EX(image, size)) @@ -1000,6 +1008,14 @@ bool CartDetector::isProbablySB(const ByteBuffer& image, size_t size) return searchForBytes(image, size, signature[1], 3); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartDetector::isProbablyTVBoy(const ByteBuffer& image, size_t size) +{ + // TV Boy cart bankswitching switches banks by accessing addresses 0x1800..$187F + uInt8 signature[5] = {0x91, 0x82, 0x6c, 0xfc, 0xff}; // STA ($82),Y; JMP ($FFFC) + return searchForBytes(image, size, signature, 5); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyUA(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 9ff193c87..11ff7ac1f 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -247,6 +247,11 @@ class CartDetector */ static bool isProbablySB(const ByteBuffer& image, size_t size); + /** + Returns true if the image is probably a TV Boy bankswitching cartridge + */ + static bool isProbablyTVBoy(const ByteBuffer& image, size_t size); + /** Returns true if the image is probably a UA bankswitching cartridge */ diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 3c2e2c80d..743a4b50e 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -70,7 +70,16 @@ class CartridgeEnhanced : public Cartridge @return true, if bank has changed */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + virtual bool bank(uInt16 bank, uInt16 segment); + + /** + Install pages for the specified bank in the system. + + @param bank The bank that should be installed in the system + + @return true, if bank has changed + */ + bool bank(uInt16 bank) override { return this->bank(bank, 0); } /** Get the current bank. diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index 2734b2793..decb634ec 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -88,7 +88,7 @@ bool CartridgeMDM::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMDM::bank(uInt16 bank, uInt16) +bool CartridgeMDM::bank(uInt16 bank) { if(bankLocked() || myBankingDisabled) return false; diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index fe17ae628..4b0786e42 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -73,12 +73,9 @@ class CartridgeMDM : public CartridgeEnhanced /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index 84cf8dac8..c6542b2b8 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -201,7 +201,7 @@ void CartridgeMNetwork::bankRAM(uInt16 bank) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMNetwork::bank(uInt16 bank, uInt16) +bool CartridgeMNetwork::bank(uInt16 bank) { if(bankLocked()) return false; diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index 7b4fdb729..95cd24b56 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -94,12 +94,9 @@ class CartridgeMNetwork : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system - @param segment The segment the bank should be using - - @return true, if bank has changed + @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 segment = 0) override; + bool bank(uInt16 bank) override; /** Get the current bank. diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 3817232c6..2f26abc99 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -717,27 +717,57 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::VidmodeStd: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::OFF); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::OFF); + myAdjustDirect = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::VidmodeRGB: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::RGB); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::RGB); + myAdjustSetting = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::VidmodeSVideo: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::SVIDEO); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::SVIDEO); + myAdjustSetting = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::VidModeComposite: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::COMPOSITE); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::COMPOSITE); + myAdjustSetting = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::VidModeBad: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::BAD); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::BAD); + myAdjustSetting = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::VidModeCustom: - if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::CUSTOM); + if(pressed && !repeated) + { + myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::CUSTOM); + myAdjustSetting = AdjustSetting::NTSC_PRESET; + myAdjustActive = true; + } return; case Event::PreviousAttribute: diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 2bb3746d4..9c84b4165 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -414,7 +414,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, } catch(const runtime_error& e) { - buf << "ERROR: " << e.what(); + buf << "ERROR: Couldn't create console (" << e.what() << ")"; Logger::error(buf.str()); return buf.str(); } diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 6fef5d589..a4a2365a7 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -523,6 +523,7 @@ true + true @@ -729,6 +730,7 @@ + @@ -1532,6 +1534,7 @@ true + true @@ -1747,6 +1750,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 0e4f58929..2a740137e 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1005,6 +1005,12 @@ Source Files\gui + + Source Files\emucore + + + Source Files\debugger + @@ -2063,6 +2069,12 @@ Header Files\gui + + Header Files\emucore + + + Header Files\debugger + From 548e8b70187b4f114f7c8b23c1d388b56c3c061a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 24 May 2020 23:50:36 +0200 Subject: [PATCH 020/104] Added TV Boy bankswitching --- src/debugger/gui/CartTVBoyWidget.cxx | 41 ++++++++++ src/debugger/gui/CartTVBoyWidget.hxx | 48 ++++++++++++ src/debugger/gui/module.mk | 1 + src/emucore/CartTVBoy.cxx | 87 +++++++++++++++++++++ src/emucore/CartTVBoy.hxx | 113 +++++++++++++++++++++++++++ src/emucore/module.mk | 1 + 6 files changed, 291 insertions(+) create mode 100644 src/debugger/gui/CartTVBoyWidget.cxx create mode 100644 src/debugger/gui/CartTVBoyWidget.hxx create mode 100644 src/emucore/CartTVBoy.cxx create mode 100644 src/emucore/CartTVBoy.hxx diff --git a/src/debugger/gui/CartTVBoyWidget.cxx b/src/debugger/gui/CartTVBoyWidget.cxx new file mode 100644 index 000000000..43fff60f7 --- /dev/null +++ b/src/debugger/gui/CartTVBoyWidget.cxx @@ -0,0 +1,41 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "CartTVBoy.hxx" +#include "CartTVBoyWidget.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartridgeTVBoyWidget::CartridgeTVBoyWidget( + GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, + int x, int y, int w, int h, CartridgeTVBoy& cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) +{ + initialize(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeTVBoyWidget::description() +{ + ostringstream info; + + info << "TV Boy, " << myCart.romBankCount() << " 4K banks\n" + << "Hotspots are from $" << Common::Base::HEX2 << 0x1800 << " to $" + << Common::Base::HEX2 << (0x1800 + myCart.romBankCount() - 1) << "\n"; + info << "Startup bank = #" << std::dec << myCart.startBank(); + + return info.str(); +} diff --git a/src/debugger/gui/CartTVBoyWidget.hxx b/src/debugger/gui/CartTVBoyWidget.hxx new file mode 100644 index 000000000..7303750a7 --- /dev/null +++ b/src/debugger/gui/CartTVBoyWidget.hxx @@ -0,0 +1,48 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CARTRIDGETVBOY_WIDGET_HXX +#define CARTRIDGETVBOY_WIDGET_HXX + +class CartridgeTVBoy; + +#include "CartEnhancedWidget.hxx" + +class CartridgeTVBoyWidget : public CartridgeEnhancedWidget +{ +public: + CartridgeTVBoyWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, + int x, int y, int w, int h, + CartridgeTVBoy& cart); + virtual ~CartridgeTVBoyWidget() = default; + +private: + string manufacturer() override { return "Akor"; } + + string description() override; + +private: + // Following constructors and assignment operators not supported + CartridgeTVBoyWidget() = delete; + CartridgeTVBoyWidget(const CartridgeTVBoyWidget&) = delete; + CartridgeTVBoyWidget(CartridgeTVBoyWidget&&) = delete; + CartridgeTVBoyWidget& operator=(const CartridgeTVBoyWidget&) = delete; + CartridgeTVBoyWidget& operator=(CartridgeTVBoyWidget&&) = delete; +}; + +#endif diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index 8f19ce5fa..d992ae85a 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -48,6 +48,7 @@ MODULE_OBJS := \ src/debugger/gui/CartMDMWidget.o \ src/debugger/gui/CartRamWidget.o \ src/debugger/gui/CartSBWidget.o \ + src/debugger/gui/CartTVBoyWidget.o \ src/debugger/gui/CartUAWidget.o \ src/debugger/gui/CartWDWidget.o \ src/debugger/gui/CartX07Widget.o \ diff --git a/src/emucore/CartTVBoy.cxx b/src/emucore/CartTVBoy.cxx new file mode 100644 index 000000000..8ce3c4549 --- /dev/null +++ b/src/emucore/CartTVBoy.cxx @@ -0,0 +1,87 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "System.hxx" +#include "CartTVBoy.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartridgeTVBoy::CartridgeTVBoy(const ByteBuffer& image, size_t size, + const string& md5, const Settings& settings) + : CartridgeEnhanced(image, size, md5, settings) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeTVBoy::checkSwitchBank(uInt16 address, uInt8) +{ + // Switch banks if necessary + if((address & ADDR_MASK) >= 0x1800 && (address & ADDR_MASK) <= 0x187F) + { + bank(address & (romBankCount() - 1)); + return true; + } + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeTVBoy::bank(uInt16 bank) +{ + if(myBankingDisabled) return false; + + bool banked = CartridgeEnhanced::bank(bank); + + // Any bankswitching locks further bankswitching, we check for bank 0 + // to avoid locking on cart init. + if (banked && bank != 0) + myBankingDisabled = true; + + return banked; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeTVBoy::save(Serializer& out) const +{ + CartridgeEnhanced::save(out); + try + { + out.putBool(myBankingDisabled); + } + catch(...) + { + cerr << "ERROR: CartridgeTVBoy::save" << endl; + return false; + } + + return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeTVBoy::load(Serializer& in) +{ + CartridgeEnhanced::load(in); + try + { + myBankingDisabled = in.getBool(); + } + catch(...) + { + cerr << "ERROR: CartridgeTVBoy::load" << endl; + return false; + } + + return true; +} diff --git a/src/emucore/CartTVBoy.hxx b/src/emucore/CartTVBoy.hxx new file mode 100644 index 000000000..670a358ff --- /dev/null +++ b/src/emucore/CartTVBoy.hxx @@ -0,0 +1,113 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CARTRIDGETVBOY_HXX +#define CARTRIDGETVBOY_HXX + +#include "bspf.hxx" +#include "CartEnhanced.hxx" +#include "System.hxx" +#ifdef DEBUGGER_SUPPORT +#include "CartTVBoyWidget.hxx" +#endif + +/** + Cartridge class used for TV Boy + There are 128 4K banks, accessing $F800..$F87F selects bank and locks any + further bankswitching. + + @author Thomas Jentzsch +*/ +class CartridgeTVBoy : public CartridgeEnhanced +{ + friend class CartridgeMDMWidget; + + public: + /** + Create a new cartridge using the specified image + + @param image Pointer to the ROM image + @param size The size of the ROM image + @param md5 The md5sum of the ROM image + @param settings A reference to the various settings (read-only) + */ + CartridgeTVBoy(const ByteBuffer& image, size_t size, const string& md5, + const Settings& settings); + virtual ~CartridgeTVBoy() = default; + + public: + /** + Install pages for the specified bank in the system. + + @param bank The bank that should be installed in the system + */ + bool bank(uInt16 bank) override; + + /** + Save the current state of this cart to the given Serializer. + + @param out The Serializer object to use + @return False on any errors, else true + */ + bool save(Serializer& out) const override; + + /** + Load the current state of this cart from the given Serializer. + + @param in The Serializer object to use + @return False on any errors, else true + */ + bool load(Serializer& in) override; + + /** + Get a descriptor for the device name (used in error checking). + + @return The name of the object + */ + string name() const override { return "CartridgeTVBoy"; } + + #ifdef DEBUGGER_SUPPORT + /** + Get debugger widget responsible for accessing the inner workings + of the cart. + */ + CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, int x, int y, int w, int h) override + { + return new CartridgeTVBoyWidget(boss, lfont, nfont, x, y, w, h, *this); + } + #endif + + private: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + + uInt16 hotspot() const override { return 0x1800; } + + private: + // Indicates whether banking has been disabled due to a bankswitch + bool myBankingDisabled{false}; + + private: + // Following constructors and assignment operators not supported + CartridgeTVBoy() = delete; + CartridgeTVBoy(const CartridgeTVBoy&) = delete; + CartridgeTVBoy(CartridgeTVBoy&&) = delete; + CartridgeTVBoy& operator=(const CartridgeTVBoy&) = delete; + CartridgeTVBoy& operator=(CartridgeTVBoy&&) = delete; +}; + +#endif diff --git a/src/emucore/module.mk b/src/emucore/module.mk index e0dd4f96f..cccda359c 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -47,6 +47,7 @@ MODULE_OBJS := \ src/emucore/CartFE.o \ src/emucore/CartMDM.o \ src/emucore/CartSB.o \ + src/emucore/CartTVBoy.o \ src/emucore/CartUA.o \ src/emucore/CartWD.o \ src/emucore/CartX07.o \ From 57f5b3c5e4982620619ccbed488489479b74cd9d Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 19:33:21 -0230 Subject: [PATCH 021/104] Unify Cartridge::bank() and CartEnhanced::bank() (take 2). Otherwise, gcc complains of methods mirroring another with the same name. --- src/emucore/Cart.hxx | 9 ++++++--- src/emucore/CartAR.cxx | 2 +- src/emucore/CartAR.hxx | 7 +++++-- src/emucore/CartBUS.cxx | 2 +- src/emucore/CartBUS.hxx | 7 +++++-- src/emucore/CartCDF.cxx | 2 +- src/emucore/CartCDF.hxx | 7 +++++-- src/emucore/CartCM.cxx | 2 +- src/emucore/CartCM.hxx | 7 +++++-- src/emucore/CartCTY.cxx | 2 +- src/emucore/CartCTY.hxx | 7 +++++-- src/emucore/CartDPCPlus.cxx | 2 +- src/emucore/CartDPCPlus.hxx | 7 +++++-- src/emucore/CartEnhanced.hxx | 11 +---------- src/emucore/CartMDM.cxx | 2 +- src/emucore/CartMDM.hxx | 7 +++++-- src/emucore/CartMNetwork.cxx | 2 +- src/emucore/CartMNetwork.hxx | 7 +++++-- src/emucore/CartTVBoy.cxx | 2 +- src/emucore/CartTVBoy.hxx | 7 +++++-- 20 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index b04a95f10..0e70f4bf7 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -140,7 +140,6 @@ class Cartridge : public Device */ uInt16 getIllegalRAMWriteAccess() const { return myRamWriteAccess; } - /** Query the access counters @@ -169,8 +168,13 @@ class Cartridge : public Device scheme defines banks in a standard format (ie, 0 for first bank, 1 for second, etc). Carts which will handle their own bankswitching completely or non-bankswitched carts can ignore this method. + + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - virtual bool bank(uInt16) { return false; } + virtual bool bank(uInt16 bank, uInt16 segment = 0) { return false; } /** Get the current bank for the provided address. Carts which have only @@ -197,7 +201,6 @@ class Cartridge : public Device */ virtual uInt16 romBankCount() const { return 1; } - /** Query the number of RAM 'banks' supported by the cartridge. Note that this information is cart-specific, where each cart basically defines diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index a0eea7486..08f803e0b 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -392,7 +392,7 @@ void CartridgeAR::loadIntoRAM(uInt8 load) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeAR::bank(uInt16 bank) +bool CartridgeAR::bank(uInt16 bank, uInt16) { if(!bankLocked()) return bankConfiguration(uInt8(bank)); diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 0bc74a291..349de38f1 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -73,9 +73,12 @@ class CartridgeAR : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index e2eb9b74a..62000118b 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -429,7 +429,7 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBUS::bank(uInt16 bank) +bool CartridgeBUS::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 3ab40f7ec..58e4eea48 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -84,9 +84,12 @@ class CartridgeBUS : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 6f9a5f4f7..09e0da3e3 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -402,7 +402,7 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCDF::bank(uInt16 bank) +bool CartridgeCDF::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 14b1eda26..62c1721ca 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -90,9 +90,12 @@ class CartridgeCDF : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index 40ec603e5..b5dfc5197 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -98,7 +98,7 @@ uInt8 CartridgeCM::column() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCM::bank(uInt16 bank) +bool CartridgeCM::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index bf8b2586e..36fa13fa8 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -141,9 +141,12 @@ class CartridgeCM : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index 822473081..dbb5d13e2 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -229,7 +229,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCTY::bank(uInt16 bank) +bool CartridgeCTY::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index fdd6c1e19..1cd682446 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -139,9 +139,12 @@ class CartridgeCTY : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index b71f5a8c0..7a0a7f4c6 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -591,7 +591,7 @@ bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDPCPlus::bank(uInt16 bank) +bool CartridgeDPCPlus::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 9617d6545..bbbf68197 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -86,9 +86,12 @@ class CartridgeDPCPlus : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 743a4b50e..3c2e2c80d 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -70,16 +70,7 @@ class CartridgeEnhanced : public Cartridge @return true, if bank has changed */ - virtual bool bank(uInt16 bank, uInt16 segment); - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - - @return true, if bank has changed - */ - bool bank(uInt16 bank) override { return this->bank(bank, 0); } + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index decb634ec..2734b2793 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -88,7 +88,7 @@ bool CartridgeMDM::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMDM::bank(uInt16 bank) +bool CartridgeMDM::bank(uInt16 bank, uInt16) { if(bankLocked() || myBankingDisabled) return false; diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index 4b0786e42..fe17ae628 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -73,9 +73,12 @@ class CartridgeMDM : public CartridgeEnhanced /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index c6542b2b8..84cf8dac8 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -201,7 +201,7 @@ void CartridgeMNetwork::bankRAM(uInt16 bank) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMNetwork::bank(uInt16 bank) +bool CartridgeMNetwork::bank(uInt16 bank, uInt16) { if(bankLocked()) return false; diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index 95cd24b56..7b4fdb729 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -94,9 +94,12 @@ class CartridgeMNetwork : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Get the current bank. diff --git a/src/emucore/CartTVBoy.cxx b/src/emucore/CartTVBoy.cxx index 8ce3c4549..b60c374c4 100644 --- a/src/emucore/CartTVBoy.cxx +++ b/src/emucore/CartTVBoy.cxx @@ -38,7 +38,7 @@ bool CartridgeTVBoy::checkSwitchBank(uInt16 address, uInt8) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeTVBoy::bank(uInt16 bank) +bool CartridgeTVBoy::bank(uInt16 bank, uInt16) { if(myBankingDisabled) return false; diff --git a/src/emucore/CartTVBoy.hxx b/src/emucore/CartTVBoy.hxx index 670a358ff..584029a5a 100644 --- a/src/emucore/CartTVBoy.hxx +++ b/src/emucore/CartTVBoy.hxx @@ -53,9 +53,12 @@ class CartridgeTVBoy : public CartridgeEnhanced /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + + @return true, if bank has changed */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 segment = 0) override; /** Save the current state of this cart to the given Serializer. From 1cfa4f1d0a7c8273a6b664c23d86681554bfb06b Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 19:40:43 -0230 Subject: [PATCH 022/104] libretro: Add TVBoy cart class. --- src/libretro/Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common index 5fafdd855..66de31b4d 100644 --- a/src/libretro/Makefile.common +++ b/src/libretro/Makefile.common @@ -81,6 +81,7 @@ SOURCES_CXX := \ $(CORE_DIR)/emucore/CartMDM.cxx \ $(CORE_DIR)/emucore/CartMNetwork.cxx \ $(CORE_DIR)/emucore/CartSB.cxx \ + $(CORE_DIR)/emucore/CartTVBoy.cxx \ $(CORE_DIR)/emucore/CartUA.cxx \ $(CORE_DIR)/emucore/CartWD.cxx \ $(CORE_DIR)/emucore/CartX07.cxx \ From a7b1928465317273cbeff9278911201c392be8bd Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 00:14:32 +0200 Subject: [PATCH 023/104] updated VS project file --- src/windows/Stella.vcxproj | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index a4a2365a7..97117b637 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -523,7 +523,6 @@ true - true @@ -663,6 +662,9 @@ true + + true + true @@ -1534,7 +1536,6 @@ true - true @@ -1674,6 +1675,9 @@ true + + true + true From d4ad7728e2bddc05b6b91c3e62c0c74d0182c7ec Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 19:47:30 -0230 Subject: [PATCH 024/104] Updated Xcode project for TVBoy class. --- src/macos/stella.xcodeproj/project.pbxproj | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index d59aac510..0c2019a93 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -407,6 +407,10 @@ DC8078DB0B4BD5F3005E9305 /* DebuggerExpressions.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC8078DA0B4BD5F3005E9305 /* DebuggerExpressions.hxx */; }; DC8078EA0B4BD697005E9305 /* UIDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC8078E60B4BD697005E9305 /* UIDialog.cxx */; }; DC8078EB0B4BD697005E9305 /* UIDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC8078E70B4BD697005E9305 /* UIDialog.hxx */; }; + DC84397B247B294E00C6A4FC /* CartTVBoy.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC843979247B294D00C6A4FC /* CartTVBoy.hxx */; }; + DC84397C247B294E00C6A4FC /* CartTVBoy.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC84397A247B294D00C6A4FC /* CartTVBoy.cxx */; }; + DC84397F247B297A00C6A4FC /* CartTVBoyWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC84397D247B297A00C6A4FC /* CartTVBoyWidget.hxx */; }; + DC843980247B297A00C6A4FC /* CartTVBoyWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC84397E247B297A00C6A4FC /* CartTVBoyWidget.cxx */; }; DC8C1BAD14B25DE7006440EE /* CartCM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC8C1BA714B25DE7006440EE /* CartCM.cxx */; }; DC8C1BAE14B25DE7006440EE /* CartCM.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC8C1BA814B25DE7006440EE /* CartCM.hxx */; }; DC8C1BAF14B25DE7006440EE /* CompuMate.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC8C1BA914B25DE7006440EE /* CompuMate.cxx */; }; @@ -700,6 +704,8 @@ isa = PBXBuildRule; compilerSpec = com.apple.compilers.llvm.clang.1_0; fileType = sourcecode.c; + inputFiles = ( + ); isEditable = 1; outputFiles = ( ); @@ -709,6 +715,8 @@ isa = PBXBuildRule; compilerSpec = com.apple.compilers.llvm.clang.1_0; fileType = sourcecode.asm; + inputFiles = ( + ); isEditable = 1; outputFiles = ( ); @@ -718,6 +726,8 @@ isa = PBXBuildRule; compilerSpec = com.apple.compilers.llvm.clang.1_0; fileType = sourcecode.cpp; + inputFiles = ( + ); isEditable = 1; outputFiles = ( ); @@ -1146,6 +1156,10 @@ DC8078DA0B4BD5F3005E9305 /* DebuggerExpressions.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = DebuggerExpressions.hxx; sourceTree = ""; }; DC8078E60B4BD697005E9305 /* UIDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = UIDialog.cxx; sourceTree = ""; }; DC8078E70B4BD697005E9305 /* UIDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = UIDialog.hxx; sourceTree = ""; }; + DC843979247B294D00C6A4FC /* CartTVBoy.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartTVBoy.hxx; sourceTree = ""; }; + DC84397A247B294D00C6A4FC /* CartTVBoy.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartTVBoy.cxx; sourceTree = ""; }; + DC84397D247B297A00C6A4FC /* CartTVBoyWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartTVBoyWidget.hxx; sourceTree = ""; }; + DC84397E247B297A00C6A4FC /* CartTVBoyWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartTVBoyWidget.cxx; sourceTree = ""; }; DC8C1BA714B25DE7006440EE /* CartCM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartCM.cxx; sourceTree = ""; }; DC8C1BA814B25DE7006440EE /* CartCM.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartCM.hxx; sourceTree = ""; }; DC8C1BA914B25DE7006440EE /* CompuMate.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompuMate.cxx; sourceTree = ""; }; @@ -1643,6 +1657,8 @@ DC2AADB3194F390F0026C7A4 /* CartRamWidget.hxx */, DC676A3D1729A0B000E4E73D /* CartSBWidget.cxx */, DC676A3E1729A0B000E4E73D /* CartSBWidget.hxx */, + DC84397E247B297A00C6A4FC /* CartTVBoyWidget.cxx */, + DC84397D247B297A00C6A4FC /* CartTVBoyWidget.hxx */, DCAAE5D11715887B0080BB82 /* CartUAWidget.cxx */, DCAAE5D21715887B0080BB82 /* CartUAWidget.hxx */, DC6D39851A3CE65000171E71 /* CartWDWidget.cxx */, @@ -1902,6 +1918,8 @@ DC71EA9C1FDA06D2008827CB /* CartMNetwork.hxx */, DC0984830D3985160073C852 /* CartSB.cxx */, DC0984840D3985160073C852 /* CartSB.hxx */, + DC84397A247B294D00C6A4FC /* CartTVBoy.cxx */, + DC843979247B294D00C6A4FC /* CartTVBoy.hxx */, 2DDBEB7008457B7D00812C11 /* CartUA.cxx */, 2DDBEB7108457B7D00812C11 /* CartUA.hxx */, DCDA03AE1A2009BA00711920 /* CartWD.cxx */, @@ -2362,6 +2380,7 @@ 2D9173CF09BA90380026E9FF /* Cart3F.hxx in Headers */, DC3EE86D1E2C0E6D00905161 /* zlib.h in Headers */, E08FCD5523A037EB0051F59B /* Blitter.hxx in Headers */, + DC84397F247B297A00C6A4FC /* CartTVBoyWidget.hxx in Headers */, E034A5EF209FB25D00C89E9E /* EmulationTiming.hxx in Headers */, DC3EE86A1E2C0E6D00905161 /* trees.h in Headers */, 2D9173D009BA90380026E9FF /* Cart4K.hxx in Headers */, @@ -2696,6 +2715,7 @@ DCAACAFB188D631500A4D282 /* CartBFSC.hxx in Headers */, DCAACAFD188D631500A4D282 /* CartDF.hxx in Headers */, DCAACAFF188D631500A4D282 /* CartDFSC.hxx in Headers */, + DC84397B247B294E00C6A4FC /* CartTVBoy.hxx in Headers */, DCAACB0F188D636F00A4D282 /* Cart4KSCWidget.hxx in Headers */, DCAACB11188D636F00A4D282 /* CartBFSCWidget.hxx in Headers */, DCA82C741FEB4E780059340F /* TimeMachineDialog.hxx in Headers */, @@ -2833,6 +2853,7 @@ 2D91747D09BA90380026E9FF /* CartE0.cxx in Sources */, DCF8621921C9D43300F95F52 /* StaggeredLogger.cxx in Sources */, E0DCD3AA20A64E96000B614E /* ConvolutionBuffer.cxx in Sources */, + DC843980247B297A00C6A4FC /* CartTVBoyWidget.cxx in Sources */, 2D91747E09BA90380026E9FF /* CartE7.cxx in Sources */, DC9616321F817830008A2206 /* PointingDeviceWidget.cxx in Sources */, 2D91747F09BA90380026E9FF /* CartF4.cxx in Sources */, @@ -3068,6 +3089,7 @@ DCDA03B01A2009BB00711920 /* CartWD.cxx in Sources */, DCC6A4B220A2622500863C59 /* SimpleResampler.cxx in Sources */, DC21E5BF21CA903E007D0E1A /* OSystemMACOS.cxx in Sources */, + DC84397C247B294E00C6A4FC /* CartTVBoy.cxx in Sources */, DCAAE5D91715887B0080BB82 /* Cart0840Widget.cxx in Sources */, DCAAE5DB1715887B0080BB82 /* CartCVWidget.cxx in Sources */, DCA233B423BAB1300032ABF3 /* Lightgun.cxx in Sources */, From 78b11d146aa315a3edb5788fdb923eb155075d1d Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 20:11:36 -0230 Subject: [PATCH 025/104] Fix paddle autodetect in a ROM; it actually uses joysticks. --- src/emucore/DefProps.hxx | 2 +- src/emucore/stella.pro | 41 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index fc0fe6155..e6cb3185d 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -3357,7 +3357,7 @@ static const BSPF::array2D DefProps = {{ { "f39e4bc99845edd8621b0f3c7b8c4fd9", "AtariAge", "", "Toyshop Trouble (AtariAge)", "F8 Emulator Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f3c431930e035a457fe370ed4d230659", "", "", "Crackpots (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f3cd0f886201d1376f3abab2df53b1b9", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "f3f5f72bfdd67f3d0e45d097e11b8091", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Submarine Commander (1982) (Sears)", "AKA Seawolf 3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f3f92aad3a335f0a1ead24a0214ff446", "", "", "Spectrum Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f40e437a9ebf0bdfe26204152f74f868", "Bit Corporation", "R320", "Jawbreaker (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index 8b783bba4..db9e694c8 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -7084,6 +7084,16 @@ "Cart.Name" "Carnival Shooter (PD)" "" +"Cart.MD5" "541cac55ebcf7891d9d51c415922303f" +"Cart.Manufacturer" "SpiceWare - Darrell Spice Jr." +"Cart.ModelNo" "SW-05" +"Cart.Name" "Stay Frosty 2" +"Cart.Note" "AtariAge Holiday Greetings 2014" +"Cart.Rarity" "Homebrew" +"Controller.Left" "JOYSTICK" +"Display.Phosphor" "YES" +"" + "Cart.MD5" "5428cdfada281c569c74c7308c7f2c26" "Cart.Manufacturer" "Activision, Larry Kaplan, David Crane" "Cart.ModelNo" "AG-010, AG-010-04" @@ -10223,6 +10233,16 @@ "Cart.Note" "Abenteuer im Urwald (Jungle Runner)" "" +"Cart.MD5" "791c88eca9836af8c34bf32b07cb58a7" +"Cart.Manufacturer" "SpiceWare - Darrell Spice Jr." +"Cart.ModelNo" "SW-05" +"Cart.Name" "Stay Frosty 2 (PAL60)" +"Cart.Note" "AtariAge Holiday Greetings 2014" +"Cart.Rarity" "Homebrew" +"Controller.Left" "JOYSTICK" +"Display.Phosphor" "YES" +"" + "Cart.MD5" "7926083ad423ed685de3b3a04a914315" "Cart.Manufacturer" "Barry Laws Jr." "Cart.Name" "Face Invaders 2 (Barry Laws Jr.) (Hack)" @@ -20241,6 +20261,8 @@ "Cart.ModelNo" "649635" "Cart.Name" "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)" "Cart.Note" "AKA Circus Atari" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" "" "Cart.MD5" "f3f5f72bfdd67f3d0e45d097e11b8091" @@ -21354,22 +21376,3 @@ "Cart.Name" "Spitfire Attack (1983) (Milton Bradley) [h1]" "" -"Cart.MD5" "541cac55ebcf7891d9d51c415922303f" -"Cart.Manufacturer" "SpiceWare - Darrell Spice Jr." -"Cart.ModelNo" "SW-05" -"Cart.Name" "Stay Frosty 2" -"Cart.Note" "AtariAge Holiday Greetings 2014" -"Cart.Rarity" "Homebrew" -"Controller.Left" "JOYSTICK" -"Display.Phosphor" "YES" -"" - -"Cart.MD5" "791c88eca9836af8c34bf32b07cb58a7" -"Cart.Manufacturer" "SpiceWare - Darrell Spice Jr." -"Cart.ModelNo" "SW-05" -"Cart.Name" "Stay Frosty 2 (PAL60)" -"Cart.Note" "AtariAge Holiday Greetings 2014" -"Cart.Rarity" "Homebrew" -"Controller.Left" "JOYSTICK" -"Display.Phosphor" "YES" -"" From 6d383b353657b9152a47c5da27671afca56b61f7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 08:36:20 +0200 Subject: [PATCH 026/104] updated docs for TV Boy bankswitching --- Changes.txt | 2 +- docs/index.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changes.txt b/Changes.txt index 616ec22f7..3d7a18ef4 100644 --- a/Changes.txt +++ b/Changes.txt @@ -53,7 +53,7 @@ * Restored 'cfg' directory for Distella config files. - * Added 3EX bank switching type. + * Added TV Boy and 3EX bank switching types. * Removed unused CV+ and DASH bank switching types. diff --git a/docs/index.html b/docs/index.html index 81185180d..98bf31b72 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4035,6 +4035,7 @@ Ms Pac-Man (Stella extended codes): FE 8K Decathlon .FE MDM Menu Driven Megacart .MDM SB 128-256K SUPERbanking .SB + TVBOY512K TV Boy (127 games).TVB, .TVBOY UA 8K UA Ltd. .UA UASW 8K UA Ltd. (swapped banks).UASW WD Wickstead Design (Pink Panther) .WD From 7c283a0ac46257616eb6821acf5b80c99f68715b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 08:55:05 +0200 Subject: [PATCH 027/104] enhanced TVBoy widget --- src/debugger/gui/CartTVBoyWidget.cxx | 46 +++++++++++++++++++++++++--- src/debugger/gui/CartTVBoyWidget.hxx | 46 ++++++++++++++++++---------- src/emucore/CartTVBoy.hxx | 2 +- 3 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/debugger/gui/CartTVBoyWidget.cxx b/src/debugger/gui/CartTVBoyWidget.cxx index 43fff60f7..5012642ba 100644 --- a/src/debugger/gui/CartTVBoyWidget.cxx +++ b/src/debugger/gui/CartTVBoyWidget.cxx @@ -16,13 +16,15 @@ //============================================================================ #include "CartTVBoy.hxx" +#include "PopUpWidget.hxx" #include "CartTVBoyWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeTVBoyWidget::CartridgeTVBoyWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeTVBoy& cart) - : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + myCartTVBoy(cart) { initialize(); } @@ -33,9 +35,45 @@ string CartridgeTVBoyWidget::description() ostringstream info; info << "TV Boy, " << myCart.romBankCount() << " 4K banks\n" - << "Hotspots are from $" << Common::Base::HEX2 << 0x1800 << " to $" - << Common::Base::HEX2 << (0x1800 + myCart.romBankCount() - 1) << "\n"; - info << "Startup bank = #" << std::dec << myCart.startBank(); + << "Hotspots are from $" << Common::Base::HEX2 << 0xf800 << " to $" + << Common::Base::HEX2 << (0xf800 + myCart.romBankCount() - 1) << "\n"; + info << CartridgeEnhancedWidget::description(); return info.str(); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeTVBoyWidget::bankSelect(int& ypos) +{ + CartridgeEnhancedWidget::bankSelect(ypos); + int xpos = myBankWidgets[0]->getRight() + _font.getMaxCharWidth() * 4; + ypos = myBankWidgets[0]->getTop(); + + myBankLocked = new CheckboxWidget(_boss, _font, xpos, ypos + 1, + "Bankswitching is locked", + kBankLocked); + myBankLocked->setTarget(this); + addFocusWidget(myBankLocked); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeTVBoyWidget::loadConfig() +{ + myBankWidgets[0]->setEnabled(!myCartTVBoy.myBankingDisabled); + myBankLocked->setState(myCartTVBoy.myBankingDisabled); + + CartridgeEnhancedWidget::loadConfig(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeTVBoyWidget::handleCommand(CommandSender* sender, + int cmd, int data, int id) +{ + if(cmd == kBankLocked) + { + myCartTVBoy.myBankingDisabled = myBankLocked->getState(); + myBankWidgets[0]->setEnabled(!myCartTVBoy.myBankingDisabled); + } + else + CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id); +} diff --git a/src/debugger/gui/CartTVBoyWidget.hxx b/src/debugger/gui/CartTVBoyWidget.hxx index 7303750a7..e1c2780e6 100644 --- a/src/debugger/gui/CartTVBoyWidget.hxx +++ b/src/debugger/gui/CartTVBoyWidget.hxx @@ -19,30 +19,44 @@ #define CARTRIDGETVBOY_WIDGET_HXX class CartridgeTVBoy; +class CheckboxWidget; #include "CartEnhancedWidget.hxx" class CartridgeTVBoyWidget : public CartridgeEnhancedWidget { -public: - CartridgeTVBoyWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, - int x, int y, int w, int h, - CartridgeTVBoy& cart); - virtual ~CartridgeTVBoyWidget() = default; + public: + CartridgeTVBoyWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, + int x, int y, int w, int h, + CartridgeTVBoy& cart); + virtual ~CartridgeTVBoyWidget() = default; -private: - string manufacturer() override { return "Akor"; } + private: + string manufacturer() override { return "Akor"; } - string description() override; + string description() override; -private: - // Following constructors and assignment operators not supported - CartridgeTVBoyWidget() = delete; - CartridgeTVBoyWidget(const CartridgeTVBoyWidget&) = delete; - CartridgeTVBoyWidget(CartridgeTVBoyWidget&&) = delete; - CartridgeTVBoyWidget& operator=(const CartridgeTVBoyWidget&) = delete; - CartridgeTVBoyWidget& operator=(CartridgeTVBoyWidget&&) = delete; + void bankSelect(int& ypos) override; + + CartridgeTVBoy& myCartTVBoy; + CheckboxWidget* myBankLocked{nullptr}; + + enum { + kBankLocked = 'bkLO' + }; + + private: + void loadConfig() override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + + private: + // Following constructors and assignment operators not supported + CartridgeTVBoyWidget() = delete; + CartridgeTVBoyWidget(const CartridgeTVBoyWidget&) = delete; + CartridgeTVBoyWidget(CartridgeTVBoyWidget&&) = delete; + CartridgeTVBoyWidget& operator=(const CartridgeTVBoyWidget&) = delete; + CartridgeTVBoyWidget& operator=(CartridgeTVBoyWidget&&) = delete; }; #endif diff --git a/src/emucore/CartTVBoy.hxx b/src/emucore/CartTVBoy.hxx index 584029a5a..90072a08d 100644 --- a/src/emucore/CartTVBoy.hxx +++ b/src/emucore/CartTVBoy.hxx @@ -34,7 +34,7 @@ */ class CartridgeTVBoy : public CartridgeEnhanced { - friend class CartridgeMDMWidget; + friend class CartridgeTVBoyWidget; public: /** From 72b5a484f0131429615bfc8f088aab5681aa2a9d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 09:19:51 +0200 Subject: [PATCH 028/104] disable scanlines by default add default pause key for macOS --- docs/index.html | 2 +- src/common/PKeyboardHandler.cxx | 4 ++++ src/emucore/Settings.cxx | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index 98bf31b72..cb5855c2b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -775,7 +775,7 @@ Pause/resume emulation Pause -   + Shift-Cmd + p diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 81b25cd6e..5f97b90a1 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -443,7 +443,11 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::LoadState, KBDK_F11}, {Event::LoadAllStates, KBDK_F11, MOD3}, {Event::TakeSnapshot, KBDK_F12}, +#ifdef BSPF_MACOS + {Event::TogglePauseMode, KBDK_P, KBDM_SHIFT | MOD3}, +#else {Event::TogglePauseMode, KBDK_PAUSE}, +#endif {Event::OptionsMenuMode, KBDK_TAB}, {Event::CmdMenuMode, KBDK_BACKSLASH}, {Event::TimeMachineMode, KBDK_T, KBDM_SHIFT}, diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 790c784bb..e6d81abdd 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -69,7 +69,7 @@ Settings::Settings() setPermanent("tv.filter", "0"); setPermanent("tv.phosphor", "byrom"); setPermanent("tv.phosblend", "50"); - setPermanent("tv.scanlines", "25"); + setPermanent("tv.scanlines", "0"); // TV options when using 'custom' mode setPermanent("tv.sharpness", "0.0"); setPermanent("tv.resolution", "0.0"); From 47e258f638c0f43738a13a63f59af919b7d989ec Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 13:58:53 +0200 Subject: [PATCH 029/104] fix cart detection for 512K ROMs add new event & hotkey for selecting previous multicart ROM --- docs/index.html | 8 +++++++- src/common/PKeyboardHandler.cxx | 1 + src/emucore/CartDetector.cxx | 19 +++++++++++++++---- src/emucore/Event.hxx | 2 +- src/emucore/EventHandler.cxx | 9 +++++++-- src/emucore/EventHandler.hxx | 2 +- src/emucore/OSystem.cxx | 6 ++++-- src/emucore/OSystem.hxx | 4 +++- 8 files changed, 39 insertions(+), 12 deletions(-) diff --git a/docs/index.html b/docs/index.html index cb5855c2b..368d16530 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1749,9 +1749,15 @@ Control + 1 + + Load previous game in ROM (multicart ROM, TIA mode) + Shift-Control + r + Shift-Control + r + + Reload current ROM (singlecart ROM, TIA mode)
- Load next game in ROM (multicart ROM, TIA mode) + Load next game in ROM (multicart ROM, TIA mode) Control + r Control + r diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5f97b90a1..4408081d7 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -459,6 +459,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::Quit, KBDK_Q, KBDM_CTRL}, #endif {Event::ReloadConsole, KBDK_R, KBDM_CTRL}, + {Event::PreviousMultiCartRom, KBDK_R, KBDM_SHIFT | KBDM_CTRL}, {Event::VidmodeDecrease, KBDK_MINUS, MOD3}, {Event::VidmodeIncrease, KBDK_EQUALS, MOD3}, diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 2ff85803d..6b48e3469 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -218,6 +218,14 @@ CartDetector::createFromMultiCart(const ByteBuffer& image, size_t& size, { // Get a piece of the larger image uInt32 i = settings.getInt("romloadcount"); + + // Move to the next game + if(!settings.getBool("romloadprev")) + i = (i + 1) % numroms; + else + i = (i - 1) % numroms; + settings.setValue("romloadcount", i); + size /= numroms; ByteBuffer slice = make_unique(size); std::copy_n(image.get()+i*size, size, slice.get()); @@ -228,9 +236,6 @@ CartDetector::createFromMultiCart(const ByteBuffer& image, size_t& size, buf << " [G" << (i+1) << "]"; id = buf.str(); - // Move to the next game the next time this ROM is loaded - settings.setValue("romloadcount", (i+1)%numroms); - if(size <= 2_KB) type = Bankswitch::Type::_2K; else if(size == 4_KB) type = Bankswitch::Type::_4K; else if(size == 8_KB) type = Bankswitch::Type::_F8; @@ -529,7 +534,13 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else if(size == 512_KB) { - if(isProbablyTVBoy(image, size)) + if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; + else if(isProbably3E(image, size)) + type = Bankswitch::Type::_3E; + else if(isProbably3F(image, size)) + type = Bankswitch::Type::_3F; + else if(isProbablyTVBoy(image, size)) type = Bankswitch::Type::_TVBOY; } else // what else can we do? diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index ddac653f3..9a6c16352 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -123,7 +123,7 @@ class Event ToggleFrameStats, ToggleSAPortOrder, ExitGame, // add new events from here to avoid that user remapped events get overwritten SettingDecrease, SettingIncrease, PreviousSetting, NextSetting, - ToggleAdaptRefresh, + ToggleAdaptRefresh, PreviousMultiCartRom, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 2f26abc99..23a9c98ee 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -544,7 +544,11 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::ReloadConsole: - if(pressed && !repeated) myOSystem.reloadConsole(); + if(pressed && !repeated) myOSystem.reloadConsole(true); + return; + + case Event::PreviousMultiCartRom: + if(pressed && !repeated) myOSystem.reloadConsole(false); return; case Event::VolumeDecrease: @@ -2172,6 +2176,7 @@ void EventHandler::exitEmulation(bool checkLauncher) EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::Quit, "Quit", "" }, { Event::ReloadConsole, "Reload current ROM/load next game", "" }, + { Event::PreviousMultiCartRom, "Load previous multicart game", "" }, { Event::ExitMode, "Exit current Stella menu/mode", "" }, { Event::OptionsMenuMode, "Enter Options menu UI", "" }, { Event::CmdMenuMode, "Toggle Commands menu UI", "" }, @@ -2409,7 +2414,7 @@ const Event::EventSet EventHandler::MiscEvents = { // Event::MouseAxisXMove, Event::MouseAxisYMove, // Event::MouseButtonLeftValue, Event::MouseButtonRightValue, Event::HandleMouseControl, Event::ToggleGrabMouse, - Event::ToggleSAPortOrder, + Event::ToggleSAPortOrder, Event::PreviousMultiCartRom }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 7d9dd235e..5d82e31b8 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -525,7 +525,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 156 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 157 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 9c84b4165..0ebefebf1 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -399,7 +399,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, // Each time a new console is loaded, we simulate a cart removal // Some carts need knowledge of this, as they behave differently // based on how many power-cycles they've been through since plugged in - mySettings->setValue("romloadcount", 0); + mySettings->setValue("romloadcount", -1); // we move to the next game initially } // Create an instance of the 2600 game console @@ -474,8 +474,10 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool OSystem::reloadConsole() +bool OSystem::reloadConsole(bool nextrom) { + mySettings->setValue("romloadprev", !nextrom); + return createConsole(myRomFile, myRomMD5, false) == EmptyString; } diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 2bc5368c6..4958efead 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -345,9 +345,11 @@ class OSystem Reloads the current console (essentially deletes and re-creates it). This can be thought of as a real console off/on toggle. + @param nextrom If true select next multicart ROM, else previous one + @return True on successful creation, otherwise false */ - bool reloadConsole(); + bool reloadConsole(bool nextrom = true); /** Creates a new ROM launcher, to select a new ROM to emulate. From c7012528e693d8fcfeb8f72096c027f54f3de6b9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 25 May 2020 18:32:13 +0200 Subject: [PATCH 030/104] reorder 512K bankswitching detection --- src/emucore/CartDetector.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 6b48e3469..eff02eed4 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -534,14 +534,14 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else if(size == 512_KB) { - if(isProbably3EX(image, size)) + if(isProbablyTVBoy(image, size)) + type = Bankswitch::Type::_TVBOY; + else if(isProbably3EX(image, size)) type = Bankswitch::Type::_3EX; else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; - else if(isProbablyTVBoy(image, size)) - type = Bankswitch::Type::_TVBOY; } else // what else can we do? { From 3946b2f4e1014d130f3ff0b58eaeda1813597873 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 25 May 2020 14:06:05 -0230 Subject: [PATCH 031/104] Add TVBoy properties to database. --- src/emucore/DefProps.hxx | 4 +++- src/emucore/stella.pro | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index e6cb3185d..333121515 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -25,7 +25,7 @@ regenerated and the application recompiled. */ -static constexpr uInt32 DEF_PROPS_SIZE = 3514; +static constexpr uInt32 DEF_PROPS_SIZE = 3516; static const BSPF::array2D DefProps = {{ { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -405,6 +405,7 @@ static const BSPF::array2D DefProps = {{ { "1b1daaa9aa5cded3d633bfcbeb06479c", "", "", "Ship Demo (V 1502) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "1b22a3d79ddd79335b69c94dd9b3e44e", "Tron", "", "Moon Patrol (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "1b4b06c2a14ed3ee73b7d0fd61b6aaf5", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b5a8da0622bffcee4c5b42aed4e0ef0", "Akor", "", "TV Boy II (1992) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "1b8c3c0bfb815b2a1010bba95998b66e", "Telegames", "", "Frogs and Flies (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "1b8d35d93697450ea26ebf7ff17bd4d1", "Quelle - Otto Versand", "176.764 9 - 781644", "Marineflieger (1983) (Quelle) (PAL)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "1bb91bae919ddbd655fa25c54ea6f532", "Suntek", "SS-026", "Treasure Island (1983) (Suntek) (PAL)", "AKA Treasure Discovery", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -1426,6 +1427,7 @@ static const BSPF::array2D DefProps = {{ { "65917ae29a8c9785bb1f2acb0d6aafd0", "", "", "Junkosoft One Year Demo (1999) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "6596b3737ae4b976e4aadb68d836c5c7", "Digivision", "", "Defender (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "659a20019de4a23c748ec2292ea5f221", "Retroactive", "", "Qb (V2.05) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "65a6f1255fe22468a8bf84ff28a4d289", "Akor", "", "Super TV Boy (1995) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "65b106eba3e45f3dab72ea907f39f8b4", "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow", "GCG 1001T", "Music Machine, The (1983) (Sparrow)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, { "65ba1a4c643d1ab44481bdddeb403827", "Quelle", "876.013 4", "Katastrophen-Einsatz (1983) (Quelle) (PAL)", "AKA M.A.S.H.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "65bd29e8ab1b847309775b0de6b2e4fe", "Coleco, Ed English", "2667", "Roc 'n Rope (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index db9e694c8..c487a6bae 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -21376,3 +21376,18 @@ "Cart.Name" "Spitfire Attack (1983) (Milton Bradley) [h1]" "" +"Cart.MD5" "1b5a8da0622bffcee4c5b42aed4e0ef0" +"Cart.Manufacturer" "Akor" +"Cart.Name" "TV Boy II (1992) (Akor)" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + +"Cart.MD5" "65a6f1255fe22468a8bf84ff28a4d289" +"Cart.Manufacturer" "Akor" +"Cart.Name" "Super TV Boy (1995) (Akor)" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" From e8640e21338e531798e0b4fa7f3470435f4cd03c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 25 May 2020 14:14:57 -0230 Subject: [PATCH 032/104] libretro: Allow ROMs that are max size for Stella (instead of requiring 1 byte less). --- src/libretro/libretro.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libretro/libretro.cxx b/src/libretro/libretro.cxx index 8caae3765..42408bd97 100644 --- a/src/libretro/libretro.cxx +++ b/src/libretro/libretro.cxx @@ -559,7 +559,7 @@ bool retro_load_game(const struct retro_game_info *info) { 0, 0, 0, 0, NULL }, }; - if(!info || info->size >= stella.getROMMax()) return false; + if(!info || info->size > stella.getROMMax()) return false; environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); From 96959a7c7d086e53109adbe64ce2b2cb9b4fd1ff Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 25 May 2020 17:32:01 -0230 Subject: [PATCH 033/104] Move 'max rom size' into a const method, and make use of it elsewhere in the code. --- src/common/bspf.hxx | 7 +++++-- src/emucore/Cart.cxx | 2 +- src/emucore/FSNode.cxx | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 3fc1aaf6c..844f12804 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -90,9 +90,9 @@ using DWordBuffer = std::unique_ptr; // NOLINT using AdjustFunction = std::function; // We use KB a lot; let's make a literal for it -constexpr uInt32 operator "" _KB(unsigned long long size) +constexpr size_t operator "" _KB(unsigned long long size) { - return static_cast(size * 1024); + return static_cast(size * 1024); } static const string EmptyString(""); @@ -128,6 +128,9 @@ namespace BSPF static const string ARCH = "NOARCH"; #endif + // Maximum size of a ROM that Stella can support + inline constexpr size_t romMaxSize() { return 512_KB; } + // Make 2D-arrays using std::array less verbose template using array2D = std::array, ROW>; diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index 7639101ff..f86c81f8c 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -83,7 +83,7 @@ uInt16 Cartridge::bankSize(uInt16 bank) const getImage(size); - return std::min(uInt32(size) / romBankCount(), 4_KB); // assuming that each bank has the same size + return std::min(size / romBankCount(), 4_KB); // assuming that each bank has the same size } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 64af7212e..acdad37ca 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -236,7 +236,7 @@ size_t FilesystemNode::read(ByteBuffer& image) const return size; // Otherwise, the default behaviour is to read from a normal C++ ifstream - image = make_unique(512 * 1024); + image = make_unique(BSPF::romMaxSize()); ifstream in(getPath(), std::ios::binary); if (in) { @@ -247,7 +247,7 @@ size_t FilesystemNode::read(ByteBuffer& image) const if (length == 0) throw runtime_error("Zero-byte file"); - size = std::min(length, 512 * 1024); + size = std::min(length, BSPF::romMaxSize()); in.read(reinterpret_cast(image.get()), size); } else From eb6c633c13e9179d4a6ff0930abf95fa003abdb1 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 25 May 2020 18:37:35 -0230 Subject: [PATCH 034/104] libretro: Use ROM size from core, update formatting and add const. --- src/libretro/FSNodeLIBRETRO.cxx | 3 +- src/libretro/StellaLIBRETRO.cxx | 87 ++++++++++++++++----------------- src/libretro/StellaLIBRETRO.hxx | 84 ++++++++++++++++++------------- 3 files changed, 96 insertions(+), 78 deletions(-) diff --git a/src/libretro/FSNodeLIBRETRO.cxx b/src/libretro/FSNodeLIBRETRO.cxx index c2ee02b97..8c242391b 100644 --- a/src/libretro/FSNodeLIBRETRO.cxx +++ b/src/libretro/FSNodeLIBRETRO.cxx @@ -15,6 +15,7 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "bspf.hxx" #include "FSNodeLIBRETRO.hxx" #ifdef _WIN32 @@ -92,7 +93,7 @@ AbstractFSNodePtr FilesystemNodeLIBRETRO::getParent() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - size_t FilesystemNodeLIBRETRO::read(ByteBuffer& image) const { - image = make_unique(512 * 1024); + image = make_unique(BSPF::romMaxSize()); extern uInt32 libretro_read_rom(void* data); return libretro_read_rom(image.get()); diff --git a/src/libretro/StellaLIBRETRO.cxx b/src/libretro/StellaLIBRETRO.cxx index d670c45a9..38e52e734 100644 --- a/src/libretro/StellaLIBRETRO.cxx +++ b/src/libretro/StellaLIBRETRO.cxx @@ -188,7 +188,6 @@ void StellaLIBRETRO::updateVideo() if(tia.scanlines() == 0) break; } - video_ready = tia.newFramePending(); if (video_ready) @@ -221,7 +220,7 @@ bool StellaLIBRETRO::loadState(const void* data, size_t size) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool StellaLIBRETRO::saveState(void* data, size_t size) +bool StellaLIBRETRO::saveState(void* data, size_t size) const { Serializer state; @@ -236,7 +235,7 @@ bool StellaLIBRETRO::saveState(void* data, size_t size) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -size_t StellaLIBRETRO::getStateSize() +size_t StellaLIBRETRO::getStateSize() const { Serializer state; @@ -247,52 +246,52 @@ size_t StellaLIBRETRO::getStateSize() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float StellaLIBRETRO::getVideoAspectPar() +float StellaLIBRETRO::getVideoAspectPar() const { float par; if (getVideoNTSC()) { - if (!video_aspect_ntsc) - { - if (video_filter != NTSCFilter::Preset::OFF) + if (!video_aspect_ntsc) { - // non-interlace square pixel clock -- 1.0 pixel @ color burst -- double-width pixels - par = (6.1363635f / 3.579545454f) / 2.0; + if (video_filter != NTSCFilter::Preset::OFF) + { + // non-interlace square pixel clock -- 1.0 pixel @ color burst -- double-width pixels + par = (6.1363635f / 3.579545454f) / 2.0; + } + else + { + // blargg filter + par = 1.0; + } } else - { - // blargg filter - par = 1.0; - } - } - else - par = video_aspect_ntsc / 100.0; + par = video_aspect_ntsc / 100.0; } else { - if (!video_aspect_pal) - { - if (video_filter != NTSCFilter::Preset::OFF) + if (!video_aspect_pal) { - // non-interlace square pixel clock -- 0.8 pixel @ color burst -- double-width pixels - par = (7.3750000f / (4.43361875f * 4.0f / 5.0f)) / 2.0f; + if (video_filter != NTSCFilter::Preset::OFF) + { + // non-interlace square pixel clock -- 0.8 pixel @ color burst -- double-width pixels + par = (7.3750000f / (4.43361875f * 4.0f / 5.0f)) / 2.0f; + } + else + { + // blargg filter + par = 1.0; + } } else - { - // blargg filter - par = 1.0; - } - } - else - par = video_aspect_pal / 100.0; + par = video_aspect_pal / 100.0; } return par; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float StellaLIBRETRO::getVideoAspect() +float StellaLIBRETRO::getVideoAspect() const { uInt32 width = myOSystem->console().tia().width() * 2; @@ -301,7 +300,7 @@ float StellaLIBRETRO::getVideoAspect() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void* StellaLIBRETRO::getVideoBuffer() +void* StellaLIBRETRO::getVideoBuffer() const { FrameBufferLIBRETRO& frame = static_cast(myOSystem->frameBuffer()); @@ -309,7 +308,7 @@ void* StellaLIBRETRO::getVideoBuffer() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool StellaLIBRETRO::getVideoNTSC() +bool StellaLIBRETRO::getVideoNTSC() const { const ConsoleInfo& console_info = myOSystem->console().about(); string format = console_info.DisplayFormat; @@ -348,13 +347,13 @@ void StellaLIBRETRO::setConsoleFormat(uInt32 mode) { switch(mode) { - case 0: console_format = "AUTO"; break; - case 1: console_format = "NTSC"; break; - case 2: console_format = "PAL"; break; - case 3: console_format = "SECAM"; break; - case 4: console_format = "NTSC50"; break; - case 5: console_format = "PAL60"; break; - case 6: console_format = "SECAM60"; break; + case 0: console_format = "AUTO"; break; + case 1: console_format = "NTSC"; break; + case 2: console_format = "PAL"; break; + case 3: console_format = "SECAM"; break; + case 4: console_format = "NTSC50"; break; + case 5: console_format = "PAL60"; break; + case 6: console_format = "SECAM60"; break; } if (system_ready) @@ -388,9 +387,9 @@ void StellaLIBRETRO::setVideoPhosphor(uInt32 mode, uInt32 blend) { switch (mode) { - case 0: video_phosphor = "byrom"; break; - case 1: video_phosphor = "never"; break; - case 2: video_phosphor = "always"; break; + case 0: video_phosphor = "byrom"; break; + case 1: video_phosphor = "never"; break; + case 2: video_phosphor = "always"; break; } video_phosphor_blend = blend; @@ -414,9 +413,9 @@ void StellaLIBRETRO::setAudioStereo(int mode) { switch (mode) { - case 0: audio_mode = "byrom"; break; - case 1: audio_mode = "mono"; break; - case 2: audio_mode = "stereo"; break; + case 0: audio_mode = "byrom"; break; + case 1: audio_mode = "mono"; break; + case 2: audio_mode = "stereo"; break; } if (system_ready) diff --git a/src/libretro/StellaLIBRETRO.hxx b/src/libretro/StellaLIBRETRO.hxx index 3078e8eb1..01c2cbaf7 100644 --- a/src/libretro/StellaLIBRETRO.hxx +++ b/src/libretro/StellaLIBRETRO.hxx @@ -32,7 +32,6 @@ #include "TIA.hxx" #include "TIASurface.hxx" - /** This class wraps Stella core for easier libretro maintenance */ @@ -52,46 +51,59 @@ class StellaLIBRETRO void runFrame(); bool loadState(const void* data, size_t size); - bool saveState(void* data, size_t size); + bool saveState(void* data, size_t size) const; public: - const char* getCoreName() { return "Stella"; } - const char* getROMExtensions() { return "a26|bin"; } + const char* getCoreName() const { return "Stella"; } + const char* getROMExtensions() const { return "a26|bin"; } - void* getROM() { return rom_image.get(); } - uInt32 getROMSize() { return rom_size; } - uInt32 getROMMax() { return 512 * 1024; } + void* getROM() const { return rom_image.get(); } + uInt32 getROMSize() const { return rom_size; } + constexpr uInt32 getROMMax() const { return BSPF::romMaxSize(); } uInt8* getRAM() { return system_ram; } - uInt32 getRAMSize() { return 128; } + constexpr uInt32 getRAMSize() const { return 128; } - size_t getStateSize(); + size_t getStateSize() const; - bool getConsoleNTSC() { return console_timing == ConsoleTiming::ntsc; } + bool getConsoleNTSC() const { return console_timing == ConsoleTiming::ntsc; } - float getVideoAspectPar(); - float getVideoAspect(); - bool getVideoNTSC(); - float getVideoRate() { return getVideoNTSC() ? 60.0 : 50.0; } + float getVideoAspectPar() const; + float getVideoAspect() const; + bool getVideoNTSC() const; + float getVideoRate() const { return getVideoNTSC() ? 60.0 : 50.0; } - bool getVideoReady() { return video_ready; } - uInt32 getVideoZoom() { return myOSystem->frameBuffer().tiaSurface().ntscEnabled() ? 2 : 1; } + bool getVideoReady() const { return video_ready; } + uInt32 getVideoZoom() const { + return myOSystem->frameBuffer().tiaSurface().ntscEnabled() ? 2 : 1; + } bool getVideoResize(); - void* getVideoBuffer(); - uInt32 getVideoWidth() { return getVideoZoom()==1 ? myOSystem->console().tia().width() : getVideoWidthMax(); } - uInt32 getVideoHeight() { return myOSystem->console().tia().height(); } - uInt32 getVideoPitch() { return getVideoWidthMax() * 4; } + void* getVideoBuffer() const; + uInt32 getVideoWidth() const { + return getVideoZoom() == 1 ? myOSystem->console().tia().width() : getVideoWidthMax(); + } + uInt32 getVideoHeight() const { + return myOSystem->console().tia().height(); + } + constexpr uInt32 getVideoPitch() const { return getVideoWidthMax() * 4; } - uInt32 getVideoWidthMax() { return AtariNTSC::outWidth(160); } - uInt32 getVideoHeightMax() { return 312; } + constexpr uInt32 getVideoWidthMax() const { return AtariNTSC::outWidth(160); } + constexpr uInt32 getVideoHeightMax() const { return 312; } - uInt32 getRenderWidth() { return getVideoZoom()==1 ? myOSystem->console().tia().width() * 2 : getVideoWidthMax(); } - uInt32 getRenderHeight() { return myOSystem->console().tia().height() * getVideoZoom(); } + uInt32 getRenderWidth() const { + return getVideoZoom() == 1 ? myOSystem->console().tia().width() * 2 + : getVideoWidthMax(); + } + uInt32 getRenderHeight() const { + return myOSystem->console().tia().height() * getVideoZoom(); + } - float getAudioRate() { return getConsoleNTSC() ? (262 * 76 * 60) / 38.0 : (312 * 76 * 50) / 38.0; } - bool getAudioReady() { return audio_samples > 0; } - uInt32 getAudioSize() { return audio_samples; } + float getAudioRate() const { + return getConsoleNTSC() ? (262 * 76 * 60) / 38.0 : (312 * 76 * 50) / 38.0; + } + bool getAudioReady() const { return audio_samples > 0; } + uInt32 getAudioSize() const { return audio_samples; } Int16* getAudioBuffer() { return audio_buffer.get(); } @@ -101,7 +113,7 @@ class StellaLIBRETRO void setConsoleFormat(uInt32 mode); void setVideoAspectNTSC(uInt32 value) { video_aspect_ntsc = value; }; - void setVideoAspectPAL(uInt32 value) { video_aspect_pal = value; }; + void setVideoAspectPAL(uInt32 value) { video_aspect_pal = value; }; void setVideoFilter(NTSCFilter::Preset mode); void setVideoPalette(const string& mode); @@ -109,12 +121,18 @@ class StellaLIBRETRO void setAudioStereo(int mode); - void setInputEvent(Event::Type type, Int32 state) { myOSystem->eventHandler().handleEvent(type, state); } + void setInputEvent(Event::Type type, Int32 state) { + myOSystem->eventHandler().handleEvent(type, state); + } - Controller::Type getLeftControllerType() { return myOSystem->console().leftController().type(); } - Controller::Type getRightControllerType() { return myOSystem->console().rightController().type(); } + Controller::Type getLeftControllerType() const { + return myOSystem->console().leftController().type(); + } + Controller::Type getRightControllerType() const { + return myOSystem->console().rightController().type(); + } - void setPaddleJoypadSensitivity(int sensitivity) + void setPaddleJoypadSensitivity(int sensitivity) { if(getLeftControllerType() == Controller::Type::Paddles) static_cast(myOSystem->console().leftController()).setDigitalSensitivity(sensitivity); @@ -137,7 +155,7 @@ class StellaLIBRETRO unique_ptr myOSystem; uInt32 system_ready; - unique_ptr rom_image; + ByteBuffer rom_image; uInt32 rom_size; string rom_path; From d11bac4afbcad62e5710f692c80a4592cef39c82 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 26 May 2020 10:33:16 +0200 Subject: [PATCH 035/104] added two more TV Boy dumps and their properties --- src/emucore/DefProps.hxx | 4 +++- src/emucore/stella.pro | 48 ++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index 333121515..65f2d67ca 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -25,7 +25,7 @@ regenerated and the application recompiled. */ -static constexpr uInt32 DEF_PROPS_SIZE = 3516; +static constexpr uInt32 DEF_PROPS_SIZE = 3518; static const BSPF::array2D DefProps = {{ { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -3148,6 +3148,7 @@ static const BSPF::array2D DefProps = {{ { "e4c666ca0c36928b95b13d33474dbb44", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "e4d41f2d59a56a9d917038682b8e0b8c", "Cody Pittman", "", "Kiss Meets Pacman (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "e4e9125a8741977583776729359614e1", "SnailSoft", "", "Comitoid beta 4 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4fa739c81b003c92bea7da5e84c7feb", "Akor", "", "TV Boy (1992) (Akor) (NTSC) [bad dump]", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "e505bd8e59e31aaed20718d47b15c61b", "Funvision - Fund. Int'l Co.", "", "Space War (1982) (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "e51030251e440cffaab1ac63438b44ae", "Parker Brothers - On-Time Software, Joe Gaucher, Louis Marbel", "PB5110", "James Bond 007 (1984) (Parker Bros)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "e51c23389e43ab328ccfb05be7d451da", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -3422,6 +3423,7 @@ static const BSPF::array2D DefProps = {{ { "f7af41a87533524d9a478575b0d873d0", "Quelle", "495.663 7", "Spiderman (1983) (Quelle) (PAL)", "AKA Spider-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f7d6592dcb773c81c278140ed4d01669", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f7e07080ed8396b68f2e5788a5c245e2", "Video Game Cartridge - Ariola", "TP-617", "Farmyard Fun (Ariola)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7ec2f2bdbe8fbea048c0d5fa6503b0b", "Akor", "", "TV Boy (1992) (Akor) (PAL)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "f7f50d9c9d28bcc9f7d3075668b7ac89", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "f7fac15cf54b55c5597718b6742dbec2", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, { "f802fa61011dd9eb6f80b271bac479d0", "Suntek", "SS-023", "Mole Hunter (1983) (Suntek) (PAL)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index c487a6bae..6253c7bfb 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -2291,6 +2291,14 @@ "Cart.Name" "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]" "" +"Cart.MD5" "1b5a8da0622bffcee4c5b42aed4e0ef0" +"Cart.Manufacturer" "Akor" +"Cart.Name" "TV Boy II (1992) (Akor)" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "1b8c3c0bfb815b2a1010bba95998b66e" "Cart.Manufacturer" "Telegames" "Cart.Name" "Frogs and Flies (1988) (Telegames) (PAL)" @@ -8536,6 +8544,14 @@ "Display.Phosphor" "YES" "" +"Cart.MD5" "65a6f1255fe22468a8bf84ff28a4d289" +"Cart.Manufacturer" "Akor" +"Cart.Name" "Super TV Boy (1995) (Akor)" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "65b106eba3e45f3dab72ea907f39f8b4" "Cart.Manufacturer" "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow" "Cart.ModelNo" "GCG 1001T" @@ -18974,6 +18990,14 @@ "Cart.Name" "Comitoid beta 4 (SnailSoft)" "" +"Cart.MD5" "e4fa739c81b003c92bea7da5e84c7feb" +"Cart.Manufacturer" "Akor" +"Cart.Name" "TV Boy (1992) (Akor) (NTSC) [bad dump]" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "e505bd8e59e31aaed20718d47b15c61b" "Cart.Manufacturer" "Funvision - Fund. Int'l Co." "Cart.Name" "Space War (1982) (Funvision) (PAL)" @@ -20633,6 +20657,14 @@ "Cart.Note" "AKA Play Farm" "" +"Cart.MD5" "f7ec2f2bdbe8fbea048c0d5fa6503b0b" +"Cart.Manufacturer" "Akor" +"Cart.Name" "TV Boy (1992) (Akor) (PAL)" +"Cart.Note" "Includes 127 games" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "f7f50d9c9d28bcc9f7d3075668b7ac89" "Cart.Manufacturer" "Activision, David Crane - Ariola" "Cart.ModelNo" "EAG-008, PAG-008, EAG-008-04I - 711 008-720" @@ -21375,19 +21407,3 @@ "Cart.MD5" "ffebb0070689b9d322687edd9c0a2bae" "Cart.Name" "Spitfire Attack (1983) (Milton Bradley) [h1]" "" - -"Cart.MD5" "1b5a8da0622bffcee4c5b42aed4e0ef0" -"Cart.Manufacturer" "Akor" -"Cart.Name" "TV Boy II (1992) (Akor)" -"Cart.Note" "Includes 127 games" -"Controller.Left" "JOYSTICK" -"Controller.Right" "JOYSTICK" -"" - -"Cart.MD5" "65a6f1255fe22468a8bf84ff28a4d289" -"Cart.Manufacturer" "Akor" -"Cart.Name" "Super TV Boy (1995) (Akor)" -"Cart.Note" "Includes 127 games" -"Controller.Left" "JOYSTICK" -"Controller.Right" "JOYSTICK" -"" From cf54e2b833897941ddf65aa98186f825b5be29a8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 26 May 2020 15:30:32 +0200 Subject: [PATCH 036/104] fixed #645 --- src/debugger/gui/Cart3EPlusWidget.cxx | 90 ++++++++++++++------------- src/debugger/gui/Cart3EPlusWidget.hxx | 9 +-- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/debugger/gui/Cart3EPlusWidget.cxx b/src/debugger/gui/Cart3EPlusWidget.cxx index 8e7cdf063..a0d97ad2b 100644 --- a/src/debugger/gui/Cart3EPlusWidget.cxx +++ b/src/debugger/gui/Cart3EPlusWidget.cxx @@ -39,7 +39,7 @@ string Cartridge3EPlusWidget::description() uInt16 numRomBanks = myCart.romBankCount(); uInt16 numRamBanks = myCart.ramBankCount(); - info << "3E+ cartridge - (4..64K ROM + RAM)\n" + info << "3E+ cartridge - (4" << ELLIPSIS << "64K ROM + RAM)\n" << " " << numRomBanks << " 1K ROM banks + " << numRamBanks << " 512b RAM banks\n" << " mapped into four segments\n" "ROM bank & segment selected by writing to $3F\n" @@ -61,6 +61,7 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) { size_t size; const uInt8* image = myCart.getImage(size); + const int VGAP = myFontHeight / 4; VariantList banktype; VarList::push_back(banktype, "ROM", "ROM"); @@ -68,6 +69,8 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) myBankWidgets = make_unique(bankSegs()); + ypos -= VGAP * 2; + for(uInt32 seg = 0; seg < bankSegs(); ++seg) { int xpos = 2, xpos_s, ypos_s = ypos + 1, width; @@ -77,20 +80,25 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) label << "Set segment " << seg << " as "; new StaticTextWidget(_boss, _font, xpos, ypos, label.str()); - ypos += myLineHeight + 8; + ypos += myLineHeight + VGAP * 2; xpos += _font.getMaxCharWidth() * 2; - CartridgeEnhancedWidget::bankList(myCart.romBankCount(), seg, items, width); + CartridgeEnhancedWidget::bankList(std::max(myCart.romBankCount(), myCart.ramBankCount()), + seg, items, width); myBankWidgets[seg] = new PopUpWidget(_boss, _font, xpos, ypos - 2, width, - myLineHeight, items, "Bank "); + myLineHeight, items, "Bank ", 0, kBankChanged); + myBankWidgets[seg]->setID(seg); + myBankWidgets[seg]->setTarget(this); addFocusWidget(myBankWidgets[seg]); xpos += myBankWidgets[seg]->getWidth(); myBankType[seg] = new PopUpWidget(_boss, _font, xpos, ypos - 2, 3 * _font.getMaxCharWidth(), - myLineHeight, banktype, " of "); + myLineHeight, banktype, " of ", 0, kRomRamChanged); + myBankType[seg]->setID(seg); + myBankType[seg]->setTarget(this); addFocusWidget(myBankType[seg]); xpos = myBankType[seg]->getRight() + _font.getMaxCharWidth(); @@ -98,7 +106,8 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) // add "Commit" button (why required?) myBankCommit[seg] = new ButtonWidget(_boss, _font, xpos, ypos - 4, _font.getStringWidth(" Commit "), myButtonHeight, - "Commit", bankEnum[seg]); + "Commit", kChangeBank); + myBankCommit[seg]->setID(seg); myBankCommit[seg]->setTarget(this); addFocusWidget(myBankCommit[seg]); @@ -117,7 +126,7 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) myBankState[2 * seg] = new EditTextWidget(_boss, _font, xoffset, ypos_s, _w - xoffset - 10, myLineHeight, ""); myBankState[2 * seg]->setEditable(false, true); - ypos_s += myLineHeight + 4; + ypos_s += myLineHeight + VGAP; label.str(""); label << "$" << Common::Base::HEX4 << addr2 << "-$" << Common::Base::HEX4 << (addr2 + 0x1FF); @@ -127,7 +136,7 @@ void Cartridge3EPlusWidget::bankSelect(int& ypos) _w - xoffset - 10, myLineHeight, ""); myBankState[2 * seg + 1]->setEditable(false, true); - ypos += 2 * myLineHeight; + ypos += myLineHeight + VGAP * 4; } } @@ -142,42 +151,44 @@ void Cartridge3EPlusWidget::loadConfig() void Cartridge3EPlusWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { - uInt16 segment = 0; + const uInt16 segment = id; + switch(cmd) { - case kBank0Changed: - segment = 0; + case kBankChanged: + case kRomRamChanged: + { + const bool isROM = myBankType[segment]->getSelectedTag() == "ROM"; + int bank = myBankWidgets[segment]->getSelected(); + + myBankCommit[segment]->setEnabled((isROM && bank < myCart.romBankCount()) + || (!isROM && bank < myCart.ramBankCount())); break; - case kBank1Changed: - segment = 1; - break; - case kBank2Changed: - segment = 2; - break; - case kBank3Changed: - segment = 3; + } + case kChangeBank: + { + // Ignore bank if either number or type hasn't been selected + if(myBankWidgets[segment]->getSelected() < 0 || + myBankType[segment]->getSelected() < 0) + return; + + uInt8 bank = myBankWidgets[segment]->getSelected(); + + myCart.unlockBank(); + + if(myBankType[segment]->getSelectedTag() == "ROM") + myCart.bank(bank, segment); + else + myCart.bank(bank + myCart.romBankCount(), segment); + + myCart.lockBank(); + invalidate(); + updateUIState(); break; + } default: break; } - - // Ignore bank if either number or type hasn't been selected - if(myBankWidgets[segment]->getSelected() < 0 || - myBankType[segment]->getSelected() < 0) - return; - - uInt8 bank = myBankWidgets[segment]->getSelected(); - - myCart.unlockBank(); - - if(myBankType[segment]->getSelectedTag() == "ROM") - myCart.bank(bank, segment); - else - myCart.bank(bank + myCart.romBankCount(), segment); - - myCart.lockBank(); - invalidate(); - updateUIState(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -234,8 +245,3 @@ string Cartridge3EPlusWidget::internalRamDescription() return desc.str(); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const std::array Cartridge3EPlusWidget::bankEnum = { - kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed -}; diff --git a/src/debugger/gui/Cart3EPlusWidget.hxx b/src/debugger/gui/Cart3EPlusWidget.hxx index 7cde61042..44473e0cf 100644 --- a/src/debugger/gui/Cart3EPlusWidget.hxx +++ b/src/debugger/gui/Cart3EPlusWidget.hxx @@ -56,13 +56,10 @@ class Cartridge3EPlusWidget : public CartridgeEnhancedWidget std::array myBankCommit{nullptr}; std::array myBankState{nullptr}; - enum BankID { - kBank0Changed = 'b0CH', - kBank1Changed = 'b1CH', - kBank2Changed = 'b2CH', - kBank3Changed = 'b3CH' + enum { + kRomRamChanged = 'rrCh', + kChangeBank = 'chBk', }; - static const std::array bankEnum; private: // Following constructors and assignment operators not supported From 91c49bd222e4d905e1f4fbf279d73ec6e3674c05 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 26 May 2020 14:55:40 -0230 Subject: [PATCH 037/104] Add support for loading grayscale PNG. Fixes #644. If I'd known it would be that easy, I'd have done it long ago. --- Changes.txt | 2 ++ src/common/PNGLibrary.cxx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Changes.txt b/Changes.txt index 3d7a18ef4..df70e30c0 100644 --- a/Changes.txt +++ b/Changes.txt @@ -57,6 +57,8 @@ * Removed unused CV+ and DASH bank switching types. + * Added support for loading grayscale PNG images in the ROM launcher. + -Have fun! diff --git a/src/common/PNGLibrary.cxx b/src/common/PNGLibrary.cxx index e1980a975..23dd798d6 100644 --- a/src/common/PNGLibrary.cxx +++ b/src/common/PNGLibrary.cxx @@ -89,7 +89,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface) } else if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - loadImageERROR("Greyscale PNG images not supported"); + png_set_gray_to_rgb(png_ptr); } else if(color_type == PNG_COLOR_TYPE_PALETTE) { From 3d06fb02581d8994422eebc3205b980baa0fb405 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 27 May 2020 10:14:16 +0200 Subject: [PATCH 038/104] added analog input filtering in UI (fixes #578) --- Changes.txt | 2 ++ src/common/PJoystickHandler.cxx | 37 +++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Changes.txt b/Changes.txt index df70e30c0..681118cc5 100644 --- a/Changes.txt +++ b/Changes.txt @@ -33,6 +33,8 @@ * Added that mouse sensitivity for Driving controller can be adjusted + * Added paddle filtering in UI to avoid unwanted navigation events + * Added selectable dialog fonts * Added separate positioning of launcher, emulator and debugger diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index 3b2452798..1af10feac 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -687,27 +687,32 @@ void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) } j->axisLastValue[axis] = value; } + #ifdef GUI_SUPPORT else if(myHandler.hasOverlay()) { - // First, clamp the values to simulate digital input - // (the only thing that the underlying code understands) - if(value > Joystick::deadzone()) - value = 32000; - else if(value < -Joystick::deadzone()) - value = -32000; - else - value = 0; - - // Now filter out consecutive, similar values - // (only pass on the event if the state has changed) - if(value != j->axisLastValue[axis]) + // A value change lower than Joystick::deadzone indicates analog input which is ignored + if((abs(j->axisLastValue[axis] - value) > Joystick::deadzone())) { -#ifdef GUI_SUPPORT - myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button); -#endif - j->axisLastValue[axis] = value; + // First, clamp the values to simulate digital input + // (the only thing that the underlying code understands) + if(value > Joystick::deadzone()) + value = 32000; + else if(value < -Joystick::deadzone()) + value = -32000; + else + value = 0; + + // Now filter out consecutive, similar values + // (only pass on the event if the state has changed) + if(value != j->axisLastValue[axis]) + { + myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button); + + } } + j->axisLastValue[axis] = value; } + #endif } } From 1518d6fc5d99075f39a0c6f3f6a35451bbf992e9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 28 May 2020 18:19:26 +0200 Subject: [PATCH 039/104] minor doc update --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 368d16530..f0687880f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1965,7 +1965,7 @@ N/A N/A N/A - N/A + voice (2600-daptor II) SaveKey From 5137b3a82ad938d5a449a6660264e52c94c7efd5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 29 May 2020 16:30:50 -0230 Subject: [PATCH 040/104] Updated changelog, removing highscore stuff until 6.3. --- Changes.txt | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Changes.txt b/Changes.txt index 681118cc5..887b8071b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -14,34 +14,30 @@ 6.1.2 to 6.2: (??? ??, 2020) - * Added high scores: Score addresses, game variation etc. can be defined for - a game. This allows the user to save high scores for these games. For each - game and variation, the top 10 scores can be saved. (TODO: Doc) - * Added interactive palette to Video & Audio settings. * Added 'Custom' palette, generated from user controlled phase shifts. - * Added that adjustable audio & video settings are displayed as gauge bars + * Added that adjustable audio & video settings are displayed as gauge bars. * Added four global hotkeys which allow selecting and changing numerous - audio & video settings without having to remember the dedicated hotkeys + audio & video settings without having to remember the dedicated hotkeys. * Added 'Turbo' mode, runs the game as fast as the computer allows. - * Added that paddle centering (per ROM) and sensitivity can be adjusted + * Added that paddle centering (per ROM) and sensitivity can be adjusted. - * Added that mouse sensitivity for Driving controller can be adjusted + * Added that mouse sensitivity for Driving controller can be adjusted. - * Added paddle filtering in UI to avoid unwanted navigation events + * Added paddle filtering in UI to avoid unwanted navigation events. - * Added selectable dialog fonts + * Added selectable dialog fonts. - * Added separate positioning of launcher, emulator and debugger + * Added separate positioning of launcher, emulator and debugger. - * Added optional display to game refresh rate adaption in fullscreen mode + * Added optional display to game refresh rate adaption in fullscreen mode. - * Added option which lets default ROM path follow launcher navigation + * Added option which lets default ROM path follow launcher navigation. * Added debugger 'saveaccess' function, which saves memory access counts to a CSV file. From bedc04aaf43319a1a965cb1e632e04154aa16be2 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 30 May 2020 17:21:06 -0230 Subject: [PATCH 041/104] Split logic for cart creation from CartDetector into new CartCreator class. Besides simplifying the class, this allows the code to be more easily integrated into HarmonyCart. --- src/emucore/CartCreator.cxx | 348 ++++++++++++++++++++++++++++++++ src/emucore/CartCreator.hxx | 96 +++++++++ src/emucore/CartDetector.cxx | 326 ------------------------------ src/emucore/CartDetector.hxx | 53 ----- src/emucore/OSystem.cxx | 4 +- src/emucore/ProfilingRunner.cxx | 5 +- src/emucore/module.mk | 1 + 7 files changed, 450 insertions(+), 383 deletions(-) create mode 100644 src/emucore/CartCreator.cxx create mode 100644 src/emucore/CartCreator.hxx diff --git a/src/emucore/CartCreator.cxx b/src/emucore/CartCreator.cxx new file mode 100644 index 000000000..fe7faed55 --- /dev/null +++ b/src/emucore/CartCreator.cxx @@ -0,0 +1,348 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "bspf.hxx" +#include "Cart.hxx" +#include "Cart0840.hxx" +#include "Cart2K.hxx" +#include "Cart3E.hxx" +#include "Cart3EX.hxx" +#include "Cart3EPlus.hxx" +#include "Cart3F.hxx" +#include "Cart4A50.hxx" +#include "Cart4K.hxx" +#include "Cart4KSC.hxx" +#include "CartAR.hxx" +#include "CartBF.hxx" +#include "CartBFSC.hxx" +#include "CartBUS.hxx" +#include "CartCDF.hxx" +#include "CartCM.hxx" +#include "CartCTY.hxx" +#include "CartCV.hxx" +#include "CartDF.hxx" +#include "CartDFSC.hxx" +#include "CartDPC.hxx" +#include "CartDPCPlus.hxx" +#include "CartE0.hxx" +#include "CartE7.hxx" +#include "CartE78K.hxx" +#include "CartEF.hxx" +#include "CartEFSC.hxx" +#include "CartF0.hxx" +#include "CartF4.hxx" +#include "CartF4SC.hxx" +#include "CartF6.hxx" +#include "CartF6SC.hxx" +#include "CartF8.hxx" +#include "CartF8SC.hxx" +#include "CartFA.hxx" +#include "CartFA2.hxx" +#include "CartFC.hxx" +#include "CartFE.hxx" +#include "CartMDM.hxx" +#include "CartSB.hxx" +#include "CartTVBoy.hxx" +#include "CartUA.hxx" +#include "CartWD.hxx" +#include "CartX07.hxx" +#include "MD5.hxx" +#include "Props.hxx" +#include "Logger.hxx" +#include "OSystem.hxx" + +#include "CartDetector.hxx" +#include "CartCreator.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +unique_ptr CartCreator::create(const FilesystemNode& file, + const ByteBuffer& image, size_t size, string& md5, + const string& propertiesType, Settings& settings) +{ + unique_ptr cartridge; + Bankswitch::Type type = Bankswitch::nameToType(propertiesType), + detectedType = type; + string id; + + // Collect some info about the ROM + ostringstream buf; + + // First inspect the file extension itself + // If a valid type is found, it will override the one passed into this method + Bankswitch::Type typeByName = Bankswitch::typeFromExtension(file); + if(typeByName != Bankswitch::Type::_AUTO) + type = detectedType = typeByName; + + // See if we should try to auto-detect the cartridge type + // If we ask for extended info, always do an autodetect + if(type == Bankswitch::Type::_AUTO || settings.getBool("rominfo")) + { + detectedType = CartDetector::autodetectType(image, size); + if(type != Bankswitch::Type::_AUTO && type != detectedType) + cerr << "Auto-detection not consistent: " + << Bankswitch::typeToName(type) << ", " + << Bankswitch::typeToName(detectedType) << endl; + + type = detectedType; + buf << Bankswitch::typeToName(type) << "*"; + } + else + buf << Bankswitch::typeToName(type); + + // Check for multicart first; if found, get the correct part of the image + switch(type) + { + case Bankswitch::Type::_2IN1: + // Make sure we have a valid sized image + if(size == 2*2_KB || size == 2*4_KB || size == 2*8_KB || size == 2*16_KB) + { + cartridge = + createFromMultiCart(image, size, 2, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_4IN1: + // Make sure we have a valid sized image + if(size == 4*2_KB || size == 4*4_KB || size == 4*8_KB) + { + cartridge = + createFromMultiCart(image, size, 4, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_8IN1: + // Make sure we have a valid sized image + if(size == 8*2_KB || size == 8*4_KB || size == 8*8_KB) + { + cartridge = + createFromMultiCart(image, size, 8, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_16IN1: + // Make sure we have a valid sized image + if(size == 16*2_KB || size == 16*4_KB || size == 16*8_KB) + { + cartridge = + createFromMultiCart(image, size, 16, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_32IN1: + // Make sure we have a valid sized image + if(size == 32*2_KB || size == 32*4_KB) + { + cartridge = + createFromMultiCart(image, size, 32, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_64IN1: + // Make sure we have a valid sized image + if(size == 64*2_KB || size == 64*4_KB) + { + cartridge = + createFromMultiCart(image, size, 64, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + case Bankswitch::Type::_128IN1: + // Make sure we have a valid sized image + if(size == 128*2_KB || size == 128*4_KB) + { + cartridge = + createFromMultiCart(image, size, 128, md5, detectedType, id, settings); + buf << id; + } + else + throw runtime_error("Invalid cart size for type '" + + Bankswitch::typeToName(type) + "'"); + break; + + default: + cartridge = createFromImage(image, size, detectedType, md5, settings); + break; + } + + if(size < 1_KB) + buf << " (" << size << "B) "; + else + buf << " (" << (size/1_KB) << "K) "; + + cartridge->setAbout(buf.str(), Bankswitch::typeToName(type), id); + + return cartridge; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +unique_ptr +CartCreator::createFromMultiCart(const ByteBuffer& image, size_t& size, + uInt32 numroms, string& md5, Bankswitch::Type type, string& id, Settings& settings) +{ + // Get a piece of the larger image + uInt32 i = settings.getInt("romloadcount"); + + // Move to the next game + if(!settings.getBool("romloadprev")) + i = (i + 1) % numroms; + else + i = (i - 1) % numroms; + settings.setValue("romloadcount", i); + + size /= numroms; + ByteBuffer slice = make_unique(size); + std::copy_n(image.get()+i*size, size, slice.get()); + + // We need a new md5 and name + md5 = MD5::hash(slice, uInt32(size)); // FIXME + ostringstream buf; + buf << " [G" << (i+1) << "]"; + id = buf.str(); + + if(size <= 2_KB) type = Bankswitch::Type::_2K; + else if(size == 4_KB) type = Bankswitch::Type::_4K; + else if(size == 8_KB) type = Bankswitch::Type::_F8; + else /* default */ type = Bankswitch::Type::_4K; + + return createFromImage(slice, size, type, md5, settings); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +unique_ptr +CartCreator::createFromImage(const ByteBuffer& image, size_t size, Bankswitch::Type type, + const string& md5, Settings& settings) +{ + // We should know the cart's type by now so let's create it + switch(type) + { + case Bankswitch::Type::_0840: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_2K: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_3E: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_3EX: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_3EP: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_3F: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_4A50: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_4K: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_4KSC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_AR: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_BF: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_BFSC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_BUS: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_CDF: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_CM: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_CTY: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_CV: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_DF: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_DFSC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_DPC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_DPCP: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_E0: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_E7: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_E78K: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_EF: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_EFSC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F0: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F4: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F4SC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F6: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F6SC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F8: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_F8SC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_FA: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_FA2: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_FC: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_FE: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_MDM: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_UA: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_UASW: + return make_unique(image, size, md5, settings, true); + case Bankswitch::Type::_SB: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_TVBOY: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_WD: + case Bankswitch::Type::_WDSW: + return make_unique(image, size, md5, settings); + case Bankswitch::Type::_X07: + return make_unique(image, size, md5, settings); + default: + return nullptr; // The remaining types have already been handled + } +} diff --git a/src/emucore/CartCreator.hxx b/src/emucore/CartCreator.hxx new file mode 100644 index 000000000..757d306ba --- /dev/null +++ b/src/emucore/CartCreator.hxx @@ -0,0 +1,96 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CARTRIDGE_CREATOR_HXX +#define CARTRIDGE_CREATOR_HXX + +class Cartridge; +class Properties; +class Settings; + +#include "Bankswitch.hxx" +#include "bspf.hxx" + +/** + Create a cartridge based on the given information. Internally, it will + use autodetection and various heuristics to determine the cart type. + + @author Stephen Anthony +*/ +class CartCreator +{ + public: + /** + Create a new cartridge object allocated on the heap. The + type of cartridge created depends on the properties object. + + @param image A pointer to the ROM image + @param size The size of the ROM image + @param md5 The md5sum for the given ROM image (can be updated) + @param dtype The detected bankswitch type of the ROM image + @param settings The settings container + @return Pointer to the new cartridge object allocated on the heap + */ + static unique_ptr create(const FilesystemNode& file, + const ByteBuffer& image, size_t size, string& md5, + const string& dtype, Settings& settings); + + private: + /** + Create a cartridge from a multi-cart image pointer; internally this + takes a slice of the ROM image ues that for the cartridge. + + @param image A pointer to the complete ROM image + @param size The size of the ROM image slice + @param numroms The number of ROMs in the multicart + @param md5 The md5sum for the slice of the ROM image + @param type The detected type of the slice of the ROM image + @param id The ID for the slice of the ROM image + @param settings The settings container + + @return Pointer to the new cartridge object allocated on the heap + */ + static unique_ptr + createFromMultiCart(const ByteBuffer& image, size_t& size, + uInt32 numroms, string& md5, Bankswitch::Type type, string& id, + Settings& settings); + + /** + Create a cartridge from the entire image pointer. + + @param image A pointer to the complete ROM image + @param size The size of the ROM image + @param type The bankswitch type of the ROM image + @param md5 The md5sum for the ROM image + @param settings The settings container + + @return Pointer to the new cartridge object allocated on the heap + */ + static unique_ptr + createFromImage(const ByteBuffer& image, size_t size, Bankswitch::Type type, + const string& md5, Settings& settings); + + private: + // Following constructors and assignment operators not supported + CartCreator() = delete; + CartCreator(const CartCreator&) = delete; + CartCreator(CartCreator&&) = delete; + CartCreator& operator=(const CartCreator&) = delete; + CartCreator& operator=(CartCreator&&) = delete; +}; + +#endif diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index eff02eed4..22ad4be9b 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -16,336 +16,10 @@ //============================================================================ #include "bspf.hxx" -#include "Cart.hxx" -#include "Cart0840.hxx" -#include "Cart2K.hxx" -#include "Cart3E.hxx" -#include "Cart3EX.hxx" -#include "Cart3EPlus.hxx" -#include "Cart3F.hxx" -#include "Cart4A50.hxx" -#include "Cart4K.hxx" -#include "Cart4KSC.hxx" -#include "CartAR.hxx" -#include "CartBF.hxx" -#include "CartBFSC.hxx" -#include "CartBUS.hxx" -#include "CartCDF.hxx" -#include "CartCM.hxx" -#include "CartCTY.hxx" -#include "CartCV.hxx" -#include "CartDF.hxx" -#include "CartDFSC.hxx" -#include "CartDPC.hxx" -#include "CartDPCPlus.hxx" -#include "CartE0.hxx" -#include "CartE7.hxx" -#include "CartE78K.hxx" -#include "CartEF.hxx" -#include "CartEFSC.hxx" -#include "CartF0.hxx" -#include "CartF4.hxx" -#include "CartF4SC.hxx" -#include "CartF6.hxx" -#include "CartF6SC.hxx" -#include "CartF8.hxx" -#include "CartF8SC.hxx" -#include "CartFA.hxx" -#include "CartFA2.hxx" -#include "CartFC.hxx" -#include "CartFE.hxx" -#include "CartMDM.hxx" -#include "CartSB.hxx" -#include "CartTVBoy.hxx" -#include "CartUA.hxx" -#include "CartWD.hxx" -#include "CartX07.hxx" -#include "MD5.hxx" -#include "Props.hxx" #include "Logger.hxx" -#include "OSystem.hxx" #include "CartDetector.hxx" -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -unique_ptr CartDetector::create(const FilesystemNode& file, - const ByteBuffer& image, size_t size, string& md5, - const string& propertiesType, Settings& settings) -{ - unique_ptr cartridge; - Bankswitch::Type type = Bankswitch::nameToType(propertiesType), - detectedType = type; - string id; - - // Collect some info about the ROM - ostringstream buf; - - // First inspect the file extension itself - // If a valid type is found, it will override the one passed into this method - Bankswitch::Type typeByName = Bankswitch::typeFromExtension(file); - if(typeByName != Bankswitch::Type::_AUTO) - type = detectedType = typeByName; - - // See if we should try to auto-detect the cartridge type - // If we ask for extended info, always do an autodetect - if(type == Bankswitch::Type::_AUTO || settings.getBool("rominfo")) - { - detectedType = autodetectType(image, size); - if(type != Bankswitch::Type::_AUTO && type != detectedType) - cerr << "Auto-detection not consistent: " - << Bankswitch::typeToName(type) << ", " - << Bankswitch::typeToName(detectedType) << endl; - - type = detectedType; - buf << Bankswitch::typeToName(type) << "*"; - } - else - buf << Bankswitch::typeToName(type); - - // Check for multicart first; if found, get the correct part of the image - switch(type) - { - case Bankswitch::Type::_2IN1: - // Make sure we have a valid sized image - if(size == 2*2_KB || size == 2*4_KB || size == 2*8_KB || size == 2*16_KB) - { - cartridge = - createFromMultiCart(image, size, 2, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_4IN1: - // Make sure we have a valid sized image - if(size == 4*2_KB || size == 4*4_KB || size == 4*8_KB) - { - cartridge = - createFromMultiCart(image, size, 4, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_8IN1: - // Make sure we have a valid sized image - if(size == 8*2_KB || size == 8*4_KB || size == 8*8_KB) - { - cartridge = - createFromMultiCart(image, size, 8, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_16IN1: - // Make sure we have a valid sized image - if(size == 16*2_KB || size == 16*4_KB || size == 16*8_KB) - { - cartridge = - createFromMultiCart(image, size, 16, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_32IN1: - // Make sure we have a valid sized image - if(size == 32*2_KB || size == 32*4_KB) - { - cartridge = - createFromMultiCart(image, size, 32, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_64IN1: - // Make sure we have a valid sized image - if(size == 64*2_KB || size == 64*4_KB) - { - cartridge = - createFromMultiCart(image, size, 64, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - case Bankswitch::Type::_128IN1: - // Make sure we have a valid sized image - if(size == 128*2_KB || size == 128*4_KB) - { - cartridge = - createFromMultiCart(image, size, 128, md5, detectedType, id, settings); - buf << id; - } - else - throw runtime_error("Invalid cart size for type '" + - Bankswitch::typeToName(type) + "'"); - break; - - default: - cartridge = createFromImage(image, size, detectedType, md5, settings); - break; - } - - if(size < 1_KB) - buf << " (" << size << "B) "; - else - buf << " (" << (size/1_KB) << "K) "; - - cartridge->setAbout(buf.str(), Bankswitch::typeToName(type), id); - - return cartridge; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -unique_ptr -CartDetector::createFromMultiCart(const ByteBuffer& image, size_t& size, - uInt32 numroms, string& md5, Bankswitch::Type type, string& id, Settings& settings) -{ - // Get a piece of the larger image - uInt32 i = settings.getInt("romloadcount"); - - // Move to the next game - if(!settings.getBool("romloadprev")) - i = (i + 1) % numroms; - else - i = (i - 1) % numroms; - settings.setValue("romloadcount", i); - - size /= numroms; - ByteBuffer slice = make_unique(size); - std::copy_n(image.get()+i*size, size, slice.get()); - - // We need a new md5 and name - md5 = MD5::hash(slice, uInt32(size)); // FIXME - ostringstream buf; - buf << " [G" << (i+1) << "]"; - id = buf.str(); - - if(size <= 2_KB) type = Bankswitch::Type::_2K; - else if(size == 4_KB) type = Bankswitch::Type::_4K; - else if(size == 8_KB) type = Bankswitch::Type::_F8; - else /* default */ type = Bankswitch::Type::_4K; - - return createFromImage(slice, size, type, md5, settings); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -unique_ptr -CartDetector::createFromImage(const ByteBuffer& image, size_t size, Bankswitch::Type type, - const string& md5, Settings& settings) -{ - // We should know the cart's type by now so let's create it - switch(type) - { - case Bankswitch::Type::_0840: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_2K: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_3E: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_3EX: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_3EP: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_3F: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_4A50: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_4K: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_4KSC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_AR: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_BF: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_BFSC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_BUS: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_CDF: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_CM: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_CTY: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_CV: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_DF: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_DFSC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_DPC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_DPCP: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_E0: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_E7: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_E78K: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_EF: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_EFSC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F0: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F4: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F4SC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F6: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F6SC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F8: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_F8SC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_FA: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_FA2: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_FC: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_FE: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_MDM: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_UA: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_UASW: - return make_unique(image, size, md5, settings, true); - case Bankswitch::Type::_SB: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_TVBOY: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_WD: - case Bankswitch::Type::_WDSW: - return make_unique(image, size, md5, settings); - case Bankswitch::Type::_X07: - return make_unique(image, size, md5, settings); - default: - return nullptr; // The remaining types have already been handled - } -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 11ff7ac1f..810ed24a7 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -18,10 +18,6 @@ #ifndef CARTRIDGE_DETECTOR_HXX #define CARTRIDGE_DETECTOR_HXX -class Cartridge; -class Properties; -class Settings; - #include "Bankswitch.hxx" #include "bspf.hxx" @@ -34,21 +30,6 @@ class Settings; class CartDetector { public: - /** - Create a new cartridge object allocated on the heap. The - type of cartridge created depends on the properties object. - - @param image A pointer to the ROM image - @param size The size of the ROM image - @param md5 The md5sum for the given ROM image (can be updated) - @param dtype The detected bankswitch type of the ROM image - @param settings The settings container - @return Pointer to the new cartridge object allocated on the heap - */ - static unique_ptr create(const FilesystemNode& file, - const ByteBuffer& image, size_t size, string& md5, - const string& dtype, Settings& settings); - /** Try to auto-detect the bankswitching type of the cartridge @@ -60,40 +41,6 @@ class CartDetector static Bankswitch::Type autodetectType(const ByteBuffer& image, size_t size); private: - /** - Create a cartridge from a multi-cart image pointer; internally this - takes a slice of the ROM image ues that for the cartridge. - - @param image A pointer to the complete ROM image - @param size The size of the ROM image slice - @param numroms The number of ROMs in the multicart - @param md5 The md5sum for the slice of the ROM image - @param type The detected type of the slice of the ROM image - @param id The ID for the slice of the ROM image - @param settings The settings container - - @return Pointer to the new cartridge object allocated on the heap - */ - static unique_ptr - createFromMultiCart(const ByteBuffer& image, size_t& size, - uInt32 numroms, string& md5, Bankswitch::Type type, string& id, - Settings& settings); - - /** - Create a cartridge from the entire image pointer. - - @param image A pointer to the complete ROM image - @param size The size of the ROM image - @param type The bankswitch type of the ROM image - @param md5 The md5sum for the ROM image - @param settings The settings container - - @return Pointer to the new cartridge object allocated on the heap - */ - static unique_ptr - createFromImage(const ByteBuffer& image, size_t size, Bankswitch::Type type, - const string& md5, Settings& settings); - /** Search the image for the specified byte signature diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 0ebefebf1..7ef0c2b4a 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -46,7 +46,7 @@ #include "FSNode.hxx" #include "MD5.hxx" #include "Cart.hxx" -#include "CartDetector.hxx" +#include "CartCreator.hxx" #include "FrameBuffer.hxx" #include "TIASurface.hxx" #include "PaletteHandler.hxx" @@ -571,7 +571,7 @@ unique_ptr OSystem::openConsole(const FilesystemNode& romfile, string& string cartmd5 = md5; const string& type = props.get(PropType::Cart_Type); unique_ptr cart = - CartDetector::create(romfile, image, size, cartmd5, type, *mySettings); + CartCreator::create(romfile, image, size, cartmd5, type, *mySettings); // Some properties may not have a name set; we can't leave it blank if(props.get(PropType::Cart_Name) == EmptyString) diff --git a/src/emucore/ProfilingRunner.cxx b/src/emucore/ProfilingRunner.cxx index e7d81b997..877d35934 100644 --- a/src/emucore/ProfilingRunner.cxx +++ b/src/emucore/ProfilingRunner.cxx @@ -20,8 +20,8 @@ #include "ProfilingRunner.hxx" #include "FSNode.hxx" -#include "CartDetector.hxx" #include "Cart.hxx" +#include "CartCreator.hxx" #include "MD5.hxx" #include "Control.hxx" #include "M6502.hxx" @@ -109,7 +109,8 @@ bool ProfilingRunner::runOne(const ProfilingRun& run) string md5 = MD5::hash(image, size); string type = ""; - unique_ptr cartridge = CartDetector::create(imageFile, image, size, md5, type, mySettings); + unique_ptr cartridge = CartCreator::create( + imageFile, image, size, md5, type, mySettings); if (!cartridge) { cout << "ERROR: unable to determine cartridge type" << endl; diff --git a/src/emucore/module.mk b/src/emucore/module.mk index cccda359c..71bd33847 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS := \ src/emucore/Bankswitch.o \ src/emucore/Booster.o \ src/emucore/Cart.o \ + src/emucore/CartCreator.o \ src/emucore/CartDetector.o \ src/emucore/CartEnhanced.o \ src/emucore/Cart0840.o \ From c6c2d9e1623542da0c4550abaa810dd3341c89b8 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 30 May 2020 17:24:07 -0230 Subject: [PATCH 042/104] libretro: Add CartCreator class. --- src/libretro/Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common index 66de31b4d..994628725 100644 --- a/src/libretro/Makefile.common +++ b/src/libretro/Makefile.common @@ -39,6 +39,7 @@ SOURCES_CXX := \ $(CORE_DIR)/emucore/Bankswitch.cxx \ $(CORE_DIR)/emucore/Booster.cxx \ $(CORE_DIR)/emucore/Cart.cxx \ + $(CORE_DIR)/emucore/CartCreator.cxx \ $(CORE_DIR)/emucore/CartDetector.cxx \ $(CORE_DIR)/emucore/CartEnhanced.cxx \ $(CORE_DIR)/emucore/Cart0840.cxx \ From 88914c493bf76dee17d2029b4576714a31212fe1 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 30 May 2020 17:34:44 -0230 Subject: [PATCH 043/104] Add CartCreator to VS project, and fix a few warnings. --- src/common/ZipHandler.hxx | 2 +- src/emucore/Cart.cxx | 4 ++-- src/emucore/CartDetector.cxx | 2 +- src/emucore/MT24LC256.hxx | 6 +++--- src/windows/Stella.vcxproj | 2 ++ src/windows/Stella.vcxproj.filters | 14 ++++++++++---- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/common/ZipHandler.hxx b/src/common/ZipHandler.hxx index 861e1350a..aaf289357 100644 --- a/src/common/ZipHandler.hxx +++ b/src/common/ZipHandler.hxx @@ -297,7 +297,7 @@ class ZipHandler void addToCache(); private: - static constexpr uInt32 DECOMPRESS_BUFSIZE = 16_KB; + static constexpr size_t DECOMPRESS_BUFSIZE = 16_KB; static constexpr uInt32 CACHE_SIZE = 8; // number of open files to cache ZipFilePtr myZip; diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index f86c81f8c..958b915df 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -80,10 +80,10 @@ bool Cartridge::bankChanged() uInt16 Cartridge::bankSize(uInt16 bank) const { size_t size; - getImage(size); - return std::min(size / romBankCount(), 4_KB); // assuming that each bank has the same size + return static_cast( + std::min(size / romBankCount(), 4_KB)); // assuming that each bank has the same size } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 22ad4be9b..0ecc6e82e 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -629,7 +629,7 @@ bool CartDetector::isProbablyFA2(const ByteBuffer& image, size_t) // file sizes // 32K version has all zeros in 29K-32K area - for(uInt32 i = 29_KB; i < 32_KB; ++i) + for(size_t i = 29_KB; i < 32_KB; ++i) if(image[i] != 0) return false; diff --git a/src/emucore/MT24LC256.hxx b/src/emucore/MT24LC256.hxx index 2832aef6c..94b894b21 100644 --- a/src/emucore/MT24LC256.hxx +++ b/src/emucore/MT24LC256.hxx @@ -46,9 +46,9 @@ class MT24LC256 public: // Sizes of the EEPROM - static constexpr uInt32 FLASH_SIZE = 32_KB; - static constexpr uInt32 PAGE_SIZE = 64; - static constexpr uInt32 PAGE_NUM = FLASH_SIZE / PAGE_SIZE; + static constexpr size_t FLASH_SIZE = 32_KB; + static constexpr size_t PAGE_SIZE = 64; + static constexpr size_t PAGE_NUM = FLASH_SIZE / PAGE_SIZE; // Initial state value of flash EEPROM static constexpr uInt8 INITIAL_VALUE = 0xff; diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 97117b637..33abbe73e 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -717,6 +717,7 @@ + @@ -1739,6 +1740,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 2a740137e..ded397f71 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1008,8 +1008,11 @@ Source Files\emucore - - Source Files\debugger + + Source Files + + + Source Files\emucore
@@ -2072,8 +2075,11 @@ Header Files\emucore - - Header Files\debugger + + Header Files + + + Header Files\emucore From 7c263c4199a3da449941982e9bfb47c46eb4e3ab Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 30 May 2020 17:47:41 -0230 Subject: [PATCH 044/104] Update Xcode project for CartCreator class. --- src/macos/stella.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index 0c2019a93..f8c0789ce 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -411,6 +411,8 @@ DC84397C247B294E00C6A4FC /* CartTVBoy.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC84397A247B294D00C6A4FC /* CartTVBoy.cxx */; }; DC84397F247B297A00C6A4FC /* CartTVBoyWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC84397D247B297A00C6A4FC /* CartTVBoyWidget.hxx */; }; DC843980247B297A00C6A4FC /* CartTVBoyWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC84397E247B297A00C6A4FC /* CartTVBoyWidget.cxx */; }; + DC857D352482F66200C7C14F /* CartCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC857D332482F66200C7C14F /* CartCreator.cxx */; }; + DC857D362482F66200C7C14F /* CartCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC857D342482F66200C7C14F /* CartCreator.hxx */; }; DC8C1BAD14B25DE7006440EE /* CartCM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC8C1BA714B25DE7006440EE /* CartCM.cxx */; }; DC8C1BAE14B25DE7006440EE /* CartCM.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC8C1BA814B25DE7006440EE /* CartCM.hxx */; }; DC8C1BAF14B25DE7006440EE /* CompuMate.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC8C1BA914B25DE7006440EE /* CompuMate.cxx */; }; @@ -1160,6 +1162,8 @@ DC84397A247B294D00C6A4FC /* CartTVBoy.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartTVBoy.cxx; sourceTree = ""; }; DC84397D247B297A00C6A4FC /* CartTVBoyWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartTVBoyWidget.hxx; sourceTree = ""; }; DC84397E247B297A00C6A4FC /* CartTVBoyWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartTVBoyWidget.cxx; sourceTree = ""; }; + DC857D332482F66200C7C14F /* CartCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartCreator.cxx; sourceTree = ""; }; + DC857D342482F66200C7C14F /* CartCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartCreator.hxx; sourceTree = ""; }; DC8C1BA714B25DE7006440EE /* CartCM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartCM.cxx; sourceTree = ""; }; DC8C1BA814B25DE7006440EE /* CartCM.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartCM.hxx; sourceTree = ""; }; DC8C1BA914B25DE7006440EE /* CompuMate.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompuMate.cxx; sourceTree = ""; }; @@ -1864,6 +1868,8 @@ CFE3F6121E84A9CE00A8204E /* CartCDF.hxx */, DC8C1BA714B25DE7006440EE /* CartCM.cxx */, DC8C1BA814B25DE7006440EE /* CartCM.hxx */, + DC857D332482F66200C7C14F /* CartCreator.cxx */, + DC857D342482F66200C7C14F /* CartCreator.hxx */, DC6727081556F4860023653B /* CartCTY.cxx */, DC6727091556F4860023653B /* CartCTY.hxx */, 2DE2DF1C0627AE07006BEC99 /* CartCV.cxx */, @@ -2582,6 +2588,7 @@ DC9EA8880F729A36000452B5 /* KidVid.hxx in Headers */, DCF7F128223D796000701A47 /* ConsoleIO.hxx in Headers */, DCF467B80F93993B00B25D7A /* SoundNull.hxx in Headers */, + DC857D362482F66200C7C14F /* CartCreator.hxx in Headers */, DCBDDE9F1D6A5F2F009DF1E9 /* Cart3EPlus.hxx in Headers */, DCF467BD0F9399F500B25D7A /* Version.hxx in Headers */, DC2B85E81EF5EF2300379EB9 /* AtariNTSC.hxx in Headers */, @@ -2914,6 +2921,7 @@ 2D9174BD09BA90380026E9FF /* Widget.cxx in Sources */, 2D9174BE09BA90380026E9FF /* CartUA.cxx in Sources */, DC3EE86E1E2C0E6D00905161 /* zutil.c in Sources */, + DC857D352482F66200C7C14F /* CartCreator.cxx in Sources */, CFE3F60B1E84A9A200A8204E /* CartBUSWidget.cxx in Sources */, DCEC58581E945125002F0246 /* DelayQueueWidget.cxx in Sources */, 2D9174BF09BA90380026E9FF /* FSNode.cxx in Sources */, From f78d880a450a7051567a13da0a688e1da88ffbe4 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 30 May 2020 22:03:10 -0230 Subject: [PATCH 045/104] Some small API changes for FSNode::getChildren(); it should only include the parent if requested. --- src/emucore/FSNode.cxx | 5 +++-- src/emucore/FSNode.hxx | 3 ++- src/unix/FSNodePOSIX.cxx | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index acdad37ca..0d9e53ad1 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -47,7 +47,8 @@ bool FilesystemNode::exists() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, - const NameFilter& filter) const + const NameFilter& filter, + bool includeParentDirectory) const { if (!_realNode || !_realNode->isDirectory()) return false; @@ -83,7 +84,7 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, ); // Add parent node, if it is valid to do so - if (hasParent()) + if (includeParentDirectory && hasParent()) { FilesystemNode parent = getParent(); parent.setName(" [..]"); diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index 2a8acc278..16360cafe 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -134,7 +134,8 @@ class FilesystemNode * does not exist). */ bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly, - const NameFilter& filter = [](const FilesystemNode&){ return true; }) const; + const NameFilter& filter = [](const FilesystemNode&){ return true; }, + bool includeParentDirectory = true) const; /** * Set/get a string representation of the name of the file. This is can be diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 33f6b5226..f483dc899 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -159,7 +159,7 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode) con if (entry._isDirectory) entry._path += "/"; - entry._isValid = entry._isDirectory || entry._isFile; + entry._isValid = true; } #endif From 32db1cc2df133ae9f69adff1d7e1539ad79cef0d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 2 Jun 2020 18:28:38 +0200 Subject: [PATCH 046/104] Save old state for "RunTo" and "RunToPC" debugger commands (fixes #650) --- src/debugger/DebuggerParser.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 49692ef8a..253131314 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1733,6 +1733,8 @@ void DebuggerParser::executeRunTo() const CartDebug& cartdbg = debugger.cartDebug(); const CartDebug::DisassemblyList& list = cartdbg.disassembly().list; + debugger.saveOldState(); + uInt32 count = 0, max_iterations = uInt32(list.size()); // Create a progress dialog box to show the progress searching through the @@ -1776,6 +1778,8 @@ void DebuggerParser::executeRunToPc() const CartDebug& cartdbg = debugger.cartDebug(); const CartDebug::DisassemblyList& list = cartdbg.disassembly().list; + debugger.saveOldState(); + uInt32 count = 0; bool done = false; constexpr uInt32 max_iterations = 1000000; From ea17bfd60468768c640bc79eda09a786789d9f86 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 2 Jun 2020 15:49:20 -0230 Subject: [PATCH 047/104] Updated version number for upcoming release. --- Announce.txt | 22 +++++++++++----------- Changes.txt | 2 +- debian/changelog | 7 +++++++ docs/debugger.html | 2 +- docs/index_r77.html | 2 +- src/common/StateManager.hxx | 2 +- src/common/Version.hxx | 2 +- src/macos/Info-Stella.plist | 4 ++-- src/unix/stella.spec | 5 ++++- src/windows/stella.rc | 8 ++++---- 10 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Announce.txt b/Announce.txt index 18f636c79..6b85d8d00 100644 --- a/Announce.txt +++ b/Announce.txt @@ -9,7 +9,7 @@ SSSS ttt eeeee llll llll aaaaa =========================================================================== - Release 6.1 for Linux, macOS and Windows + Release 6.2 for Linux, macOS and Windows =========================================================================== The Atari 2600 Video Computer System (VCS), introduced in 1977, was the @@ -21,27 +21,27 @@ all of your favourite Atari 2600 games again! Stella was originally developed for Linux by Bradford W. Mott, however, it has been ported to a number of other platforms and is currently maintained by Stephen Anthony. -This is the 6.1 release of Stella for Linux, macOS and Windows. The +This is the 6.2 release of Stella for Linux, macOS and Windows. The distributions currently available are: * Binaries for Windows Vista/7/8/10 : - Stella-6.1-win32.exe (32-bit EXE installer) - Stella-6.1-x64.exe (64-bit EXE installer) - Stella-6.1-windows.zip (32/64 bit versions) + Stella-6.2-win32.exe (32-bit EXE installer) + Stella-6.2-x64.exe (64-bit EXE installer) + Stella-6.2-windows.zip (32/64 bit versions) * Binary distribution for macOS 10.7 and above : - Stella-6.1-macos.dmg (64-bit Intel) + Stella-6.2-macos.dmg (64-bit Intel) * Binary distribution in 32-bit & 64-bit Ubuntu DEB format : - stella_6.1-1_i386.deb - stella_6.1-1_amd64.deb + stella_6.2-1_i386.deb + stella_6.2-1_amd64.deb * Binary distribution in 32-bit & 64-bit RPM format : - stella-6.1-2.i386.rpm - stella-6.1-2.x86_64.rpm + stella-6.2-2.i386.rpm + stella-6.2-2.x86_64.rpm * Source code distribution for all platforms : - stella-6.1-src.tar.xz + stella-6.2-src.tar.xz Distribution Site diff --git a/Changes.txt b/Changes.txt index 887b8071b..fceea0039 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,7 +12,7 @@ Release History =========================================================================== -6.1.2 to 6.2: (??? ??, 2020) +6.1.2 to 6.2: (June 7, 2020) * Added interactive palette to Video & Audio settings. diff --git a/debian/changelog b/debian/changelog index 81ab67bce..6b4dff642 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stella (6.2-1) stable; urgency=high + + * Version 6.2 release + + -- Stephen Anthony Sun, 7 Jun 2020 17:09:59 -0230 + + stella (6.1.2-1) stable; urgency=high * Version 6.1.2 release diff --git a/docs/debugger.html b/docs/debugger.html index 423a20aa1..7f2cabec5 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -15,7 +15,7 @@
Stella
-

Release 6.1

+

Release 6.2

Integrated Debugger

(a work in progress)


diff --git a/docs/index_r77.html b/docs/index_r77.html index 710f5e561..33e767c7e 100644 --- a/docs/index_r77.html +++ b/docs/index_r77.html @@ -58,7 +58,7 @@

Stella for RetroN 77

Atari 2600 VCS emulator

-
Release 6.1
+
Release 6.2

Quick Navigation Guide


diff --git a/src/common/StateManager.hxx b/src/common/StateManager.hxx index 3da98499c..a69a48cd5 100644 --- a/src/common/StateManager.hxx +++ b/src/common/StateManager.hxx @@ -18,7 +18,7 @@ #ifndef STATE_MANAGER_HXX #define STATE_MANAGER_HXX -#define STATE_HEADER "06010000state" +#define STATE_HEADER "06020000state" class OSystem; class RewindManager; diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 09c706540..65aa59489 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.2_pre" +#define STELLA_VERSION "6.2_beta1" #define STELLA_BUILD "5741" #endif diff --git a/src/macos/Info-Stella.plist b/src/macos/Info-Stella.plist index 8f37a40c3..386e378fc 100644 --- a/src/macos/Info-Stella.plist +++ b/src/macos/Info-Stella.plist @@ -45,7 +45,7 @@ CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion - 6.1 + 6.2 CFBundleName Stella CFBundlePackageType @@ -53,7 +53,7 @@ CFBundleSignature StLa CFBundleVersion - 6.1 + 6.2 LSApplicationCategoryType public.app-category.games LSMinimumSystemVersionByArchitecture diff --git a/src/unix/stella.spec b/src/unix/stella.spec index 796217ea6..264b4da7e 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -1,5 +1,5 @@ %define name stella -%define version 6.1.2 +%define version 6.2 %define rel 1 %define enable_sound 1 @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version} %_datadir/icons/large/%{name}.png %changelog +* Sun Jun 7 2020 Stephen Anthony 6.2-1 +- Version 6.2 release + * Sat Apr 25 2020 Stephen Anthony 6.1.2-1 - Version 6.1.2 release diff --git a/src/windows/stella.rc b/src/windows/stella.rc index d6fcd5ce3..7facd2292 100755 --- a/src/windows/stella.rc +++ b/src/windows/stella.rc @@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,1,0,0 - PRODUCTVERSION 6,1,0,0 + FILEVERSION 6,2,0,0 + PRODUCTVERSION 6,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -55,12 +55,12 @@ BEGIN VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2." VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)" VALUE "FileDescription", "Stella" - VALUE "FileVersion", "6.1" + VALUE "FileVersion", "6.2" VALUE "InternalName", "Stella" VALUE "LegalCopyright", "Copyright (c) 1995-2020 The Stella Team" VALUE "OriginalFilename", "Stella.exe" VALUE "ProductName", "Stella" - VALUE "ProductVersion", "6.1" + VALUE "ProductVersion", "6.2" END END BLOCK "VarFileInfo" From 1daf02b82772f8eef330c8351601f7d944258682 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 2 Jun 2020 21:42:25 +0200 Subject: [PATCH 048/104] improved keyboard detection (JamLoopy demo) --- src/emucore/ControllerDetector.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 023302d81..6609340df 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -314,13 +314,14 @@ bool ControllerDetector::usesKeyboard(const uInt8* image, size_t size, else if(port == Controller::Jack::Right) { // check for INPT2 *AND* INPT3 access - const int NUM_SIGS_0_0 = 5; + const int NUM_SIGS_0_0 = 6; const int SIG_SIZE_0_0 = 3; uInt8 signature_0_0[NUM_SIGS_0_0][SIG_SIZE_0_0] = { { 0x24, 0x3a, 0x30 }, // bit INPT2|$30; bmi { 0xa5, 0x3a, 0x10 }, // lda INPT2|$30; bpl { 0xa4, 0x3a, 0x30 }, // ldy INPT2|$30; bmi { 0x24, 0x0a, 0x30 }, // bit INPT2; bmi + { 0x24, 0x0a, 0x10 }, // bit INPT2; bpl { 0xa6, 0x0a, 0x30 } // ldx INPT2; bmi }; const int NUM_SIGS_0_2 = 1; @@ -329,13 +330,14 @@ bool ControllerDetector::usesKeyboard(const uInt8* image, size_t size, { 0xb5, 0x38, 0x29, 0x80, 0xd0 } // lda INPT2,x; and #80; bne }; - const int NUM_SIGS_1_0 = 5; + const int NUM_SIGS_1_0 = 6; const int SIG_SIZE_1_0 = 3; uInt8 signature_1_0[NUM_SIGS_1_0][SIG_SIZE_1_0] = { { 0x24, 0x3b, 0x30 }, // bit INPT3|$30; bmi { 0xa5, 0x3b, 0x10 }, // lda INPT3|$30; bpl { 0xa4, 0x3b, 0x30 }, // ldy INPT3|$30; bmi { 0x24, 0x0b, 0x30 }, // bit INPT3; bmi + { 0x24, 0x0b, 0x10 }, // bit INPT3; bpl { 0xa6, 0x0b, 0x30 } // ldx INPT3; bmi }; const int NUM_SIGS_1_2 = 1; From 8c9cbc87cbca62ec475a3023f257e6e57c6d8ca9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 3 Jun 2020 12:22:30 +0200 Subject: [PATCH 049/104] updated doc --- docs/index.html | 87 ++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/docs/index.html b/docs/index.html index f0687880f..abe4e09db 100644 --- a/docs/index.html +++ b/docs/index.html @@ -70,7 +70,7 @@


-
February 1999 - ??? 2020
+
February 1999 - June 2020
The Stella Team
Stella Homepage
@@ -2342,9 +2342,10 @@ -
-joyallow4 <1|0>
- Allow all 4 directions on a joystick to be pressed - simultaneously. +
-psense <number>
+ Sensitivity for emulation of paddles when using analog paddles. + Valid range of values is from 1 to 30, with larger numbers causing + faster movement. @@ -2357,6 +2358,41 @@ Impact of fast paddle movement on input averaging. + +
-dcsense <number>
+ Sensitivity for emulation of driving controllers when using a mouse. + Valid range of values is from 1 to 20, with larger numbers causing + faster movement. + + + +
-joyallow4 <1|0>
+ Allow all 4 directions on a joystick to be pressed + simultaneously. + + + +
-modcombo <1|0>
+ Use modifier(Shift/Alt/Control)-x key combos. This is normally enabled, + since the 'Quit' command is tied to 'Control-q'. However, there are times + when you want to disable them.
+ E.g. a 2-player game is using either the 'f' or 'r' keys for movement, + and pressing Control (for Fire) will perform an unwanted action + associated with Control-r or Control-f default keys. + + + +
-saport <lr|rl>
+ Determines how to enumerate the Stelladaptor/2600-daptor devices in the + order they are found: 'lr' means first is left port, second is right port, + 'rl' means the opposite. + + + +
-avoxport <name>
+ Set the name of the serial port where an AtariVox is connected. + +
-usemouse <always|analog|never>
Use mouse as a controller as specified by ROM properties in specific case. @@ -2364,24 +2400,6 @@ (paddles, trackball, etc.). - -
-grabmouse <1|0>
- Locks the mouse cursor in the game window in emulation mode. - - - -
-cursor <0|1|2|3>
- Set mouse cursor state in UI/emulation modes. - - - -
-dsense <number>
- Sensitivity for emulation of paddles when using a digital device - (ie, joystick digital axis or button, keyboard key, etc.). - Valid range of values is from 1 to 20, with larger numbers causing - faster movement. - -
-msense <number>
Sensitivity for emulation of paddles when using a mouse. @@ -2397,27 +2415,21 @@ -
-dcsense <number>
- Sensitivity for emulation of driving controllers when using a mouse. +
-dsense <number>
+ Sensitivity for emulation of paddles when using a digital device + (ie, joystick digital axis or button, keyboard key, etc.). Valid range of values is from 1 to 20, with larger numbers causing faster movement. -
-saport <lr|rl>
- Determines how to enumerate the Stelladaptor/2600-daptor devices in the - order they are found: 'lr' means first is left port, second is right port, - 'rl' means the opposite. +
-cursor <0|1|2|3>
+ Set mouse cursor state in UI/emulation modes. -
-modcombo <1|0>
- Use modifier(Shift/Alt/Control)-x key combos. This is normally enabled, - since the 'Quit' command is tied to 'Control-q'. However, there are times - when you want to disable them.
- E.g. a 2-player game is using either the 'f' or 'r' keys for movement, - and pressing Control (for Fire) will perform an unwanted action - associated with Control-r or Control-f default keys. +
-grabmouse <1|0>
+ Locks the mouse cursor in the game window in emulation mode. @@ -2588,11 +2600,6 @@ Make the start path follow ROM launcher navigation. - -
-avoxport <name>
- Set the name of the serial port where an AtariVox is connected. - -
-maxres <WxH>
Useful for developers, this sets the maximum size of window that From 73ac91b624e523a9d28ebb1a248b61c18523984e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 4 Jun 2020 09:55:13 +0200 Subject: [PATCH 050/104] fix #648 (focus problem in debugger) --- src/debugger/DebuggerParser.cxx | 2 ++ src/debugger/gui/DebuggerDialog.cxx | 1 + 2 files changed, 3 insertions(+) diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 253131314..9e3c0745b 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -112,6 +112,8 @@ string DebuggerParser::run(const string& command) if(validateArgs(i)) { myCommand = i; + if(commands[i].refreshRequired) + debugger.baseDialog()->saveConfig(); commands[i].executor(this); } diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 6674311f6..be9ad7515 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -251,6 +251,7 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd, break; case kDDOptionsCmd: + saveConfig(); myOptions->open(); loadConfig(); break; From badb41c4edb53965e11f25425fd1dcaf44ced736 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 24 May 2020 16:08:24 -0230 Subject: [PATCH 051/104] Shorten error messages in ROM launcher, to fix overflow of buffer width. --- src/emucore/OSystem.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 7ef0c2b4a..0d1364790 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -414,7 +414,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, } catch(const runtime_error& e) { - buf << "ERROR: Couldn't create console (" << e.what() << ")"; + buf << "ERROR: " << e.what(); Logger::error(buf.str()); return buf.str(); } From bc8211b4436b03ab264f20ab4185c16a30a0ed18 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 5 Jun 2020 18:04:08 +0200 Subject: [PATCH 052/104] take care of odd ROM sizes (fixes #653) --- src/emucore/CartEnhanced.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 27fa425b5..4d22deb39 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -278,7 +278,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] >> myBankShift; + return myCurrentSegOffset[std::min((address & ROM_MASK) >> myBankShift, romBankCount() - 1)] >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -290,7 +290,8 @@ uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::romBankCount() const { - return uInt16(mySize >> myBankShift); + // take care of too small ROMs + return uInt16(mySize + ((1 << myBankShift) - 1)) >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 76a8468a66b03eb61085cc87bc9fe0d41723aa25 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 6 Jun 2020 15:01:14 -0230 Subject: [PATCH 053/104] Final commit before branching for 6.2 release. --- src/common/Version.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 65aa59489..3f020344f 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.2_beta1" -#define STELLA_BUILD "5741" +#define STELLA_VERSION "6.2" +#define STELLA_BUILD "5995" #endif From 1476d460e5dbc8afa30f77b691ae05f1b35007a5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 6 Jun 2020 16:37:13 -0230 Subject: [PATCH 054/104] And as usual, some last minute updates. --- src/common/Version.hxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 2 +- src/emucore/CartEnhanced.cxx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 3f020344f..569ef060e 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.2" -#define STELLA_BUILD "5995" +#define STELLA_BUILD "5996" #endif diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index 0bf38f529..af110cb0d 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -125,7 +125,7 @@ string CartridgeEnhancedWidget::romDescription() start -= start % std::min(int(size), 0x1000); end = start + uInt16(myCart.mySize) - 1; // special check for ROMs where the extra RAM is not included in the image (e.g. CV). - if((start & 0xFFF) < size) + if((start & 0xFFFU) < size) { start += myCart.myRomOffset; } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 4d22deb39..def9c8072 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -44,7 +44,7 @@ void CartridgeEnhanced::install(System& system) // or the ROM is < 4K (-> 1 segment) myBankSegs = std::min(1 << (MAX_BANK_SHIFT - myBankShift), int(mySize) / myBankSize); // e.g. = 1 - myRomOffset = myRamBankCount > 0 ? 0 : uInt32(myRamSize) * 2; + myRomOffset = myRamBankCount > 0U ? 0U : static_cast(myRamSize * 2); myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) myWriteOffset = myRamWpHigh ? ramSize : 0; // e.g. = 0x0000 myReadOffset = myRamWpHigh ? 0 : ramSize; // e.g. = 0x0080 @@ -315,7 +315,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) } else { - if((address & myBankMask) < myRamSize * 2) + if(static_cast(address & myBankMask) < myRamSize * 2) { // Normally, a write to the read port won't do anything // However, the patch command is special in that ignores such From bfe33e25b71a681e416ef7118cd0fd3af929d7d5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 7 Jun 2020 08:22:07 +0200 Subject: [PATCH 055/104] fix ROMs >= 64K (partially addresses #654) --- src/emucore/CartEnhanced.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 4d22deb39..ccd2d0e1a 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -291,7 +291,7 @@ uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const uInt16 CartridgeEnhanced::romBankCount() const { // take care of too small ROMs - return uInt16(mySize + ((1 << myBankShift) - 1)) >> myBankShift; + return uInt16((mySize + ((1 << myBankShift) - 1)) >> myBankShift); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From dbc0baf9f075343fd5ce70cbbb9826491e8c88f6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 7 Jun 2020 14:49:27 -0230 Subject: [PATCH 056/104] Fix some common errors causing crashes when ROM sizes aren't what we expect (fixes #654). --- src/common/bspf.hxx | 9 +++++ src/emucore/Cart0840.cxx | 2 +- src/emucore/Cart2K.cxx | 34 +--------------- src/emucore/Cart3E.cxx | 2 +- src/emucore/Cart3F.cxx | 2 +- src/emucore/Cart4K.cxx | 2 +- src/emucore/CartBF.cxx | 2 +- src/emucore/CartCV.cxx | 10 ++--- src/emucore/CartDF.cxx | 2 +- src/emucore/CartE0.cxx | 2 +- src/emucore/CartEF.cxx | 2 +- src/emucore/CartEnhanced.cxx | 78 ++++++++++++++++++++++++++++++++---- src/emucore/CartEnhanced.hxx | 5 ++- src/emucore/CartF0.cxx | 2 +- src/emucore/CartF4.cxx | 2 +- src/emucore/CartF6.cxx | 2 +- src/emucore/CartF8.cxx | 2 +- src/emucore/CartFA.cxx | 2 +- src/emucore/CartFC.cxx | 2 +- src/emucore/CartFE.cxx | 2 +- src/emucore/CartMDM.cxx | 2 +- src/emucore/CartSB.cxx | 2 +- src/emucore/CartTVBoy.cxx | 2 +- src/emucore/CartUA.cxx | 2 +- src/emucore/CartWD.cxx | 4 +- src/emucore/CartX07.cxx | 2 +- 26 files changed, 109 insertions(+), 71 deletions(-) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 844f12804..24fe8d0a7 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -131,6 +131,15 @@ namespace BSPF // Maximum size of a ROM that Stella can support inline constexpr size_t romMaxSize() { return 512_KB; } + // Get next power of two greater than or equal to the given value + inline size_t nextPowerOfTwo(size_t size) { + if(size < 2) return 1; + size_t power2 = 1; + while(power2 < size) + power2 <<= 1; + return power2; + } + // Make 2D-arrays using std::array less verbose template using array2D = std::array, ROW>; diff --git a/src/emucore/Cart0840.cxx b/src/emucore/Cart0840.cxx index e071f61a2..894b8eed7 100644 --- a/src/emucore/Cart0840.cxx +++ b/src/emucore/Cart0840.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { } diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index f4d4ef7bd..c70cc373f 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -21,38 +21,6 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 2_KB, md5, settings) { - // Size can be a maximum of 2K - if(size > 2_KB) - size = 2_KB; - - // Set image size to closest power-of-two for the given size - mySize = 1; myBankShift = 0; - while(mySize < size) - { - mySize <<= 1; - myBankShift++; - } - - // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam - size_t bufSize = std::max(mySize, System::PAGE_SIZE); - myImage = make_unique(bufSize); - std::fill_n(myImage.get(), bufSize, 0x02); - - // Handle cases where ROM is smaller than the page size - // It's much easier to do it this way rather than changing the page size - if(mySize >= System::PAGE_SIZE) - { - // Directly copy the ROM image into the buffer - std::copy_n(image.get(), mySize, myImage.get()); - } - else - { - // Manually 'mirror' the ROM image into the buffer - for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) - std::copy_n(image.get(), mySize, myImage.get() + i); - mySize = System::PAGE_SIZE; - myBankShift = 6; - } } diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index be69d105d..263c8b2e9 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 21b21b9c7..20d9cef1d 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3F::Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index 9e684afad..0a3e27bdc 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -21,6 +21,6 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4K::Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 4_KB, md5, settings) { } diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index ce3c53198..065b657dc 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBF::CartridgeBF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 256_KB, md5, settings) { } diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index 8d7ac9d89..8e8e6504e 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -21,23 +21,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 2_KB, md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; myRamWpHigh = RAM_HIGH_WP; - if(mySize == 4_KB) + if(size == 4_KB) { // The game has something saved in the RAM // Useful for MagiCard program listings - // Allocate array for the ROM image - mySize = 2_KB; - myImage = make_unique(mySize); - // Copy the ROM image into my buffer - std::copy_n(image.get() + mySize, mySize, myImage.get()); + std::copy_n(image.get() + 2_KB, 2_KB, myImage.get()); myInitialRAM = make_unique(1_KB); // Copy the RAM image into a buffer for use in reset() diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index 0f4d9a1ca..f95ebcc93 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 128_KB, md5, settings) { } diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index 07afae5a2..7a10c3e34 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE0::CartridgeE0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 039f4aa5c..175b42263 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index c7378670a..363ffcd59 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -15,20 +15,84 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "Logger.hxx" #include "System.hxx" #include "CartEnhanced.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + size_t bsSize, const string& md5, + const Settings& settings) + : Cartridge(settings, md5) { - // Allocate array for the ROM image (at least 64 bytzes) - myImage = make_unique(std::max(uInt32(mySize), uInt32(System::PAGE_SIZE))); + // ROMs are not always at the 'legal' size for their associated + // bankswitching scheme; here we deal with the differing sizes + if(size != bsSize) + { + // Is the ROM too large? If so, we cap it + if(size > bsSize) + { + ostringstream buf; + buf << "ROM larger than expected (" << size << " > " << bsSize << "), truncating\n"; + Logger::info(buf.str()); - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); + size = bsSize; + } + + // Set image size to closest power-of-two for the given size + // This only applies for sizes less than the standard bank size + if(size < 4_KB) + { + mySize = 1; myBankShift = 0; + while(mySize < size) + { + mySize <<= 1; + myBankShift++; + } + } + else + mySize = size; + + // Initialize ROM with all 0's, to fill areas that the ROM may not cover + size_t bufSize = std::max(mySize, System::PAGE_SIZE); + myImage = make_unique(bufSize); + std::fill_n(myImage.get(), bufSize, 0); + + // Handle cases where ROM is smaller than the page size + // It's much easier to do it this way rather than changing the page size + if(mySize >= System::PAGE_SIZE) + { + if(size < mySize) + { + ostringstream buf; + buf << "ROM smaller than expected (" << mySize << " > " << size + << "), appending " << (mySize - size) << " bytes\n"; + Logger::info(buf.str()); + } + + // TODO: should we mirror here too?? + // Directly copy the ROM image into the buffer + std::copy_n(image.get(), mySize, myImage.get()); + } + else + { + // Manually 'mirror' the ROM image into the buffer + for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) + std::copy_n(image.get(), mySize, myImage.get() + i); + mySize = System::PAGE_SIZE; + myBankShift = 6; + } + } + else + { + mySize = size; + + // Allocate array for the ROM image + myImage = make_unique(mySize); + + // Copy the ROM image into my buffer + std::copy_n(image.get(), mySize, myImage.get()); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 3c2e2c80d..be0ac95de 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -42,10 +42,11 @@ class CartridgeEnhanced : public Cartridge @param image Pointer to the ROM image @param size The size of the ROM image @param md5 The md5sum of the ROM image + @param bsSize The size specified by the bankswitching scheme @param settings A reference to the various settings (read-only) */ - CartridgeEnhanced(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + CartridgeEnhanced(const ByteBuffer& image, size_t size, size_t bsSize, + const string& md5, const Settings& settings); virtual ~CartridgeEnhanced() = default; public: diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index 8747c57f3..f21bba07e 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF0::CartridgeF0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { } diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index 6a8cd6e00..609fd0b03 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4::CartridgeF4(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 32_KB, md5, settings) { } diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 50e993e26..572909952 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6::CartridgeF6(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 16_KB, md5, settings) { } diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index 5d898091c..7ea1216a5 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8::CartridgeF8(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { } diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index 082e403f7..bc82dec84 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 12_KB, md5, settings) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index c415ba1af..9b945c666 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFC::CartridgeFC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 7c3debda3..a9602e88a 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFE::CartridgeFE(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { myDirectPeek = false; } diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index 2734b2793..022bc1bdb 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeMDM::CartridgeMDM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 5caa01be7..8ad55f28d 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeSB::CartridgeSB(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) { } diff --git a/src/emucore/CartTVBoy.cxx b/src/emucore/CartTVBoy.cxx index b60c374c4..0626da0aa 100644 --- a/src/emucore/CartTVBoy.cxx +++ b/src/emucore/CartTVBoy.cxx @@ -21,7 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeTVBoy::CartridgeTVBoy(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 512_KB, md5, settings) { } diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 74ccc3773..23caa5091 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -22,7 +22,7 @@ CartridgeUA::CartridgeUA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, bool swapHotspots) - : CartridgeEnhanced(image, size, md5, settings), + : CartridgeEnhanced(image, size, 8_KB, md5, settings), mySwappedHotspots(swapHotspots) { } diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index 11ebc653e..f9c7463f3 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -23,10 +23,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeWD::CartridgeWD(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 8_KB, md5, settings) { // Copy the ROM image into my buffer - if (mySize == 8_KB + 3) + if(size == 8_KB + 3) { // swap banks 2 & 3 of bad dump and correct size std::copy_n(image.get() + 1_KB * 3, 1_KB * 1, myImage.get() + 1_KB * 2); diff --git a/src/emucore/CartX07.cxx b/src/emucore/CartX07.cxx index ac40b6ac6..e28869920 100644 --- a/src/emucore/CartX07.cxx +++ b/src/emucore/CartX07.cxx @@ -23,7 +23,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeX07::CartridgeX07(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) + : CartridgeEnhanced(image, size, 64_KB, md5, settings) { } From fec22a56c58a6ab2bc0681ffd225659078d745fc Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 7 Jun 2020 15:34:38 -0230 Subject: [PATCH 057/104] Update warning message when truncating ROMs in the ROM buffer. --- src/common/Version.hxx | 2 +- src/emucore/CartEnhanced.cxx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 569ef060e..ec5610431 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.2" -#define STELLA_BUILD "5996" +#define STELLA_BUILD "6000" #endif diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 363ffcd59..c809cfab6 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -33,7 +33,8 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, if(size > bsSize) { ostringstream buf; - buf << "ROM larger than expected (" << size << " > " << bsSize << "), truncating\n"; + buf << "ROM larger than expected (" << size << " > " << bsSize + << "), truncating " << (size - bsSize) << " bytes\n"; Logger::info(buf.str()); size = bsSize; From 081682e2b57f2fed37427230499eb46a6d79ebf3 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 7 Jun 2020 17:40:42 -0230 Subject: [PATCH 058/104] And it never ends. Fix broken support for 2K ROMs. --- src/common/Version.hxx | 2 +- src/emucore/CartEnhanced.cxx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index ec5610431..e19349fae 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.2" -#define STELLA_BUILD "6000" +#define STELLA_BUILD "6001" #endif diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index c809cfab6..5295364f1 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -87,6 +87,8 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, else { mySize = size; + if(mySize < 4_KB) + myBankShift = 11; // Allocate array for the ROM image myImage = make_unique(mySize); From 082b8dd9dccfbb50d33e57ea31b8bf8e963eb065 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 7 Jun 2020 18:34:10 -0230 Subject: [PATCH 059/104] A small reprieve for gcc6 users. Fixed codebase so it compiles in g++6 again. Note that we're moving to gcc7 fairly soon, so this won't be for long. Bumped version number. --- src/common/PaletteHandler.hxx | 4 ++-- src/common/Version.hxx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index bd102d9f0..3de835d7d 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -125,8 +125,8 @@ class PaletteHandler /** Convert adjustables from/to 100% scale */ - constexpr float scaleFrom100(float x) const { return (x / 50.F) - 1.F; } - constexpr uInt32 scaleTo100(float x) const { return uInt32(50 * (x + 1.F)); } + static constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; } + static constexpr uInt32 scaleTo100(float x) { return uInt32(50 * (x + 1.F)); } /** Convert palette settings name to enumeration. diff --git a/src/common/Version.hxx b/src/common/Version.hxx index e19349fae..2c770f57f 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.2" +#define STELLA_VERSION "6.2.1_pre" #define STELLA_BUILD "6001" #endif From 77aafee4cc8305c0b4f58f899625b1e125a8cbbb Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 7 Jun 2020 20:16:34 -0230 Subject: [PATCH 060/104] Updated changelog; I forgot something for the 6.2 release. --- Changes.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Changes.txt b/Changes.txt index fceea0039..aeb71411b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,6 +12,16 @@ Release History =========================================================================== +6.2 to 6.2.1: (XXX xx, 2020) + + * A ROM properties file may now be placed next to the ROM (with the same + name as the ROM, except ending in .pro), and Stella will automatically + apply the properties to the ROM. [NOTE: this was present in 6.2, but + was mistakenly left out of the changelog] + +-Have fun! + + 6.1.2 to 6.2: (June 7, 2020) * Added interactive palette to Video & Audio settings. @@ -57,8 +67,6 @@ * Added support for loading grayscale PNG images in the ROM launcher. --Have fun! - 6.1.1 to 6.1.2: (April 25, 2020) From 632d19a301d1b551c748b909ce938078fbc668c8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 8 Jun 2020 15:27:08 +0200 Subject: [PATCH 061/104] make NTSC custom phase shift not affect Yellow anymore (fixes #656) --- src/common/PaletteHandler.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index d2a2a7768..0483b6bb9 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -385,7 +385,7 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) for(int chroma = 1; chroma < NUM_CHROMA; chroma++) { color[chroma][0] = SATURATION * sinf(offset + shift * (chroma - 1)); - color[chroma][1] = SATURATION * sinf(offset + shift * (chroma - 1 - BSPF::PI_f)); + color[chroma][1] = SATURATION * cosf(offset + shift * (chroma - 1) - BSPF::PI_f); } for(int chroma = 0; chroma < NUM_CHROMA; chroma++) From d57479fa2b197df5712586799244e6b291d01ced Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 8 Jun 2020 10:59:11 -0230 Subject: [PATCH 062/104] Updated documentation with changes to properties key names. --- docs/index.html | 52 ++++++++++++++++++++++---------------------- src/tools/PropSet.pm | 44 ++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/index.html b/docs/index.html index abe4e09db..69e1aff77 100644 --- a/docs/index.html +++ b/docs/index.html @@ -549,7 +549,7 @@ have to do anything yourself. However, it is also possible to force the bankswitch type to use by adding a special filename extension. These extensions are listed in the ROM properties section under - Cartridge.Type -> File Extension.

+ Cart.Type -> File Extension.

Note: These extensions are the same as those used by the Harmony Cart and Unocart and are not case-sensitive, so you can name your files and have them @@ -2732,7 +2732,7 @@

-bs <type>
- Set "Cartridge.Type" property. See the Game Properties section + Set "Cart.Type" property. See the Game Properties section for valid types. @@ -2743,27 +2743,27 @@
-startbank <bank>
- Set "Cartridge.StartBank" property. + Set "Cart.StartBank" property.
-channels <Mono|Stereo>
- Set "Cartridge.Sound" property. + Set "Cart.Sound" property.
-ld <A|B>
- Set "Console.LeftDifficulty" property. + Set "Console.LeftDiff" property.
-rd <A|B>
- Set "Console.RightDifficulty" property. + Set "Console.RightDiff" property.
-tv <Color|BW>
- Set "Console.TelevisionType" property. + Set "Console.TVType" property. @@ -3962,24 +3962,24 @@ Ms Pac-Man (Stella extended codes):

    ; Comments
-   "Cartridge.MD5"      "Value"
-   "Property"           "Value"
+   "Cart.MD5"  "Value"
+   "Property"  "Value"
    ""
 
    ; Comments
-   "Cartridge.MD5"      "Value"
-   "Property"           "Value"
+   "Cart.MD5"  "Value"
+   "Property"  "Value"
    ""
 
    . . .
 
    ; Comments
-   "Cartridge.MD5"      "Value"
-   "Property"           "Value"
+   "Cart.MD5"  "Value"
+   "Property"  "Value"
    ""

Every block in the property file must have a unique value for the - Cartridge.MD5 property.

+ Cart.MD5 property.

Properties

@@ -3993,7 +3993,7 @@ Ms Pac-Man (Stella extended codes): - + - + @@ -4100,7 +4100,7 @@ Ms Pac-Man (Stella extended codes): - + @@ -4081,7 +4081,7 @@ Ms Pac-Man (Stella extended codes): diff --git a/src/gui/SnapshotDialog.cxx b/src/gui/SnapshotDialog.cxx index 870a82b54..e7f5795ed 100644 --- a/src/gui/SnapshotDialog.cxx +++ b/src/gui/SnapshotDialog.cxx @@ -89,7 +89,7 @@ SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent, // Snapshot in 1x mode (ignore scaling) ypos += lineHeight + VGAP; mySnap1x = new CheckboxWidget(this, font, xpos, ypos, - "Ignore scaling (1x mode)"); + "Create pixel-exact image (no zoom/post-processing)"); wid.push_back(mySnap1x); // Add Defaults, OK and Cancel buttons From 5423bc17187ced08a6884f48fd436823a5dd2085 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 11 Jun 2020 17:30:27 +0200 Subject: [PATCH 076/104] changed all adjustable steps to 1% updated changes --- Changes.txt | 4 +++- src/common/PaletteHandler.cxx | 2 +- src/common/tv_filters/NTSCFilter.cxx | 2 +- src/gui/VideoAudioDialog.cxx | 3 +-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Changes.txt b/Changes.txt index 507bfc84f..48c78a4b6 100644 --- a/Changes.txt +++ b/Changes.txt @@ -23,7 +23,9 @@ * Make NTSC custom phase shift not affect Yellow anymore. - * Allow changing palette adjustables in 1% steps again. + * Allow changing custom palette and TV effects adjustables in 1% steps again. + + * Fixed custom palette and TV effects adjustable slider rounding issue. * Fixed some bugs in 3E+ scheme when using non-standard ROM sizes. diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index 0483b6bb9..ec0d7691b 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -139,7 +139,7 @@ void PaletteHandler::changeCurrentAdjustable(int direction) { int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value); - newVal = BSPF::clamp(newVal + direction * 2, 0, 100); + newVal = BSPF::clamp(newVal + direction * 1, 0, 100); *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal); diff --git a/src/common/tv_filters/NTSCFilter.cxx b/src/common/tv_filters/NTSCFilter.cxx index 8e7e899c9..5a61dd140 100644 --- a/src/common/tv_filters/NTSCFilter.cxx +++ b/src/common/tv_filters/NTSCFilter.cxx @@ -119,7 +119,7 @@ void NTSCFilter::changeCurrentAdjustable(int direction, // return "'Custom' TV mode not selected"; newValue = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value); - newValue = BSPF::clamp(newValue + direction * 2, 0, 100); + newValue = BSPF::clamp(newValue + direction * 1, 0, 100); *ourCustomAdjustables[myCurrentAdjustable].value = scaleFrom100(newValue); diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 7fcc65cf8..23e7692cc 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -47,7 +47,7 @@ new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, \ desc, lwidth, cmd, fontWidth*4, "%"); \ myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \ - myTV ## obj->setStepValue(2); \ + myTV ## obj->setStepValue(1); \ myTV ## obj->setTickmarkIntervals(2); \ wid.push_back(myTV ## obj); \ ypos += lineHeight + VGAP; @@ -233,7 +233,6 @@ void VideoAudioDialog::addPaletteTab() CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", kPaletteUpdated) - myTVHue->setStepValue(1); // The resulting palette xpos = myPhaseShiftNtsc->getRight() + fontWidth * 2; From f2cddf2de6ca935cd9d34de795c8701da86862a3 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 11 Jun 2020 17:36:35 +0200 Subject: [PATCH 077/104] updated snapshot snapshot :) --- docs/graphics/launcher_options_snapshots.png | Bin 3586 -> 3034 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/graphics/launcher_options_snapshots.png b/docs/graphics/launcher_options_snapshots.png index 0d2b2e8d6ad728ab3caefd16fb1bbd2c6fcaba40..a833f8bb327b74e26b2fab74d400a9067c22808f 100644 GIT binary patch literal 3034 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 Date: Thu, 11 Jun 2020 19:04:39 -0230 Subject: [PATCH 078/104] Handle creation of 2K/Sub2K and all other cart types separately. This simplifies the logic in both cases, and fixes a few corner cases. --- src/emucore/Cart2K.cxx | 24 ++++++++++ src/emucore/CartEnhanced.cxx | 91 +++++++++--------------------------- 2 files changed, 47 insertions(+), 68 deletions(-) diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index ee0974549..3324e60df 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -24,4 +24,28 @@ Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, size_t bsSize) : CartridgeEnhanced(image, size, md5, settings, bsSize) { + // When creating a 2K cart, we always initially create a buffer of size 2_KB + // Sometimes we only use a portion of that buffer; we check for that now + + // Size can be a maximum of 2K + size = std::min(size, bsSize); + + // Set image size to closest power-of-two for the given size + mySize = 1; myBankShift = 0; + while(mySize < size) + { + mySize <<= 1; + myBankShift++; + } + + // Handle cases where ROM is smaller than the page size + // It's much easier to do it this way rather than changing the page size + if(mySize < System::PAGE_SIZE) + { + // Manually 'mirror' the ROM image into the buffer + for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) + std::copy_n(image.get(), mySize, myImage.get() + i); + mySize = System::PAGE_SIZE; + myBankShift = 6; + } } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 574dacca8..6cc3b0ca6 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -27,78 +27,33 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, { // ROMs are not always at the 'legal' size for their associated // bankswitching scheme; here we deal with the differing sizes - if(size != bsSize) + + // Is the ROM too large? If so, we cap it + if(size > bsSize) { - // Is the ROM too large? If so, we cap it - if(size > bsSize) - { - ostringstream buf; - buf << "ROM larger than expected (" << size << " > " << bsSize - << "), truncating " << (size - bsSize) << " bytes\n"; - Logger::info(buf.str()); - - size = bsSize; - } - - // Set image size to closest power-of-two for the given size - // This only applies for sizes less than the standard bank size - if(size < 4_KB) - { - mySize = 1; myBankShift = 0; - while(mySize < size) - { - mySize <<= 1; - myBankShift++; - } - } - else - // Make sure to use size defined by the bankswitching scheme - mySize = std::max(size, bsSize); - - // Initialize ROM with all 0's, to fill areas that the ROM may not cover - size_t bufSize = std::max(mySize, System::PAGE_SIZE); - myImage = make_unique(bufSize); - std::fill_n(myImage.get(), bufSize, 0); - - // Handle cases where ROM is smaller than the page size - // It's much easier to do it this way rather than changing the page size - if(mySize >= System::PAGE_SIZE) - { - if(size < mySize) - { - ostringstream buf; - buf << "ROM smaller than expected (" << mySize << " > " << size - << "), appending " << (mySize - size) << " bytes\n"; - Logger::info(buf.str()); - } - - // TODO: should we mirror here too?? - // Directly copy the ROM image into the buffer - // Only copy up to the amount of data the ROM provides; extra unused - // space will be filled with 0's from above - std::copy_n(image.get(), std::min(mySize, size), myImage.get()); - } - else - { - // Manually 'mirror' the ROM image into the buffer - for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) - std::copy_n(image.get(), mySize, myImage.get() + i); - mySize = System::PAGE_SIZE; - myBankShift = 6; - } + ostringstream buf; + buf << "ROM larger than expected (" << size << " > " << bsSize + << "), truncating " << (size - bsSize) << " bytes\n"; + Logger::info(buf.str()); } - else + else if(size < mySize) { - mySize = size; - if(mySize < 4_KB) - myBankShift = 11; - - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); + ostringstream buf; + buf << "ROM smaller than expected (" << mySize << " > " << size + << "), appending " << (mySize - size) << " bytes\n"; + Logger::info(buf.str()); } + + mySize = bsSize; + + // Initialize ROM with all 0's, to fill areas that the ROM may not cover + myImage = make_unique(mySize); + std::fill_n(myImage.get(), mySize, 0); + + // Directly copy the ROM image into the buffer + // Only copy up to the amount of data the ROM provides; extra unused + // space will be filled with 0's from above + std::copy_n(image.get(), std::min(mySize, size), myImage.get()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From aba80851afd541a0ef232633230b407a6adb9c9c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 12 Jun 2020 12:48:15 +0200 Subject: [PATCH 079/104] fix #663 (illegal segment access) --- src/emucore/CartEnhanced.cxx | 26 ++++++++++++++++++-------- src/emucore/CartEnhanced.hxx | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 6cc3b0ca6..83947db63 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -155,8 +155,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // This is a read access to a write port! // Reading from the write port triggers an unwanted write // The RAM banks follow the ROM banks and are half the size of a ROM bank - return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], - peekAddress); + return peekRAM(myRAM[ramAddressSegmentOffset(peekAddress) + address], peekAddress); } address &= ROM_MASK; @@ -168,8 +167,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) return peekRAM(myRAM[address], peekAddress); } - return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - + (peekAddress & myBankMask)]; + return myImage[romAddressSegmentOffset(peekAddress) + (peekAddress & myBankMask)]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -190,7 +188,7 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { address &= myRamMask; // The RAM banks follow the ROM banks and are half the size of a ROM bank - pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], + pokeRAM(myRAM[ramAddressSegmentOffset(pokeAddress) + address], pokeAddress, value); return true; } @@ -300,10 +298,22 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) return myBankChanged = true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const +{ + return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::ramAddressSegmentOffset(uInt16 address) const +{ + return uInt16(myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] >> myBankShift; + return romAddressSegmentOffset(address) >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -335,7 +345,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) { if(isRamBank(address)) { - myRAM[((myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; + myRAM[ramAddressSegmentOffset(address) + (address & myRamMask)] = value; } else { @@ -347,7 +357,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) myRAM[address & myRamMask] = value; } else - myImage[myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] + (address & myBankMask)] = value; + myImage[romAddressSegmentOffset(address) + (address & myBankMask)] = value; } return myBankChanged = true; diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index e15fb8ba1..c50f88aa6 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -256,6 +256,7 @@ class CartridgeEnhanced : public Cartridge @param address The address to check @param value The optional value used to determine the bank switched to + @return True if a bank switch happened. */ virtual bool checkSwitchBank(uInt16 address, uInt8 value = 0) = 0; @@ -268,6 +269,22 @@ class CartridgeEnhanced : public Cartridge */ virtual uInt16 getStartBank() const { return 0; } + /** + Get the ROM offset of the segment of the given address + + @param address The address to get the offset for + @return The calculated offset + */ + uInt16 romAddressSegmentOffset(uInt16 address) const; + + /** + Get the RAM offset of the segment of the given address + + @param address The address to get the offset for + @return The calculated offset + */ + uInt16 ramAddressSegmentOffset(uInt16 address) const; + private: // Following constructors and assignment operators not supported CartridgeEnhanced() = delete; From c6a9775e25348d8e838840a83f11e445ddb89199 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 12 Jun 2020 09:24:15 -0230 Subject: [PATCH 080/104] Attempt to gain a little speed on frequently used functions. --- src/emucore/CartEnhanced.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 83947db63..28b8b026c 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -299,13 +299,13 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const +inline uInt16 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const { return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEnhanced::ramAddressSegmentOffset(uInt16 address) const +inline uInt16 CartridgeEnhanced::ramAddressSegmentOffset(uInt16 address) const { return uInt16(myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1; } From 1519f50f79a98f2bb82e11fae21e4d907d50c3e8 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 12 Jun 2020 10:54:25 -0230 Subject: [PATCH 081/104] Eliminate magic number. --- src/emucore/Cart2K.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index 3324e60df..d204d93ed 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -46,6 +46,6 @@ Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) std::copy_n(image.get(), mySize, myImage.get() + i); mySize = System::PAGE_SIZE; - myBankShift = 6; + myBankShift = System::PAGE_SHIFT; } } From 8b8eb035b1a8f75780debc5b3ab508c2aaef765a Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Mon, 15 Jun 2020 23:35:20 +0200 Subject: [PATCH 082/104] Fix ROM dir for profiling. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 939f0d7cf..08cfc640c 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,7 @@ EXECUTABLE := stella$(EXEEXT) EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT) EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT) -PROFILE_DIR = $(CURDIR)/profile +PROFILE_DIR = $(CURDIR)/test/roms/profile PROFILE_OUT = $(PROFILE_DIR)/out PROFILE_STAMP = profile.stamp From 2cb7fe15fce8c64a2e856461273373a920b89ccb Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 16 Jun 2020 14:44:44 -0230 Subject: [PATCH 083/104] Fix reading from TIA registers when D6 is not used. Also fix randomization with 'tiadriven' to always fully randomize, with no relationship to what was on the data bus (fixes #664). --- Changes.txt | 6 ++++- src/emucore/System.hxx | 22 ----------------- src/emucore/tia/TIA.cxx | 52 +++++++++++++++++++---------------------- 3 files changed, 29 insertions(+), 51 deletions(-) diff --git a/Changes.txt b/Changes.txt index 48c78a4b6..3e2c16150 100644 --- a/Changes.txt +++ b/Changes.txt @@ -23,7 +23,11 @@ * Make NTSC custom phase shift not affect Yellow anymore. - * Allow changing custom palette and TV effects adjustables in 1% steps again. + * Allow changing custom palette and TV effects adjustables in 1% steps + again. + + * Fixed incorrectly setting D6 bit on TIA reads in some cases. Related + to this, improve 'tiadriven' option to randomize only D5..D0 bits. * Fixed custom palette and TV effects adjustable slider rounding issue. diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index dab87b28a..b0660fec7 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -168,28 +168,6 @@ class System : public Serializable */ uInt8 getDataBusState() const { return myDataBusState; } - /** - Get the current state of the data bus in the system, taking into - account that certain bits are in Z-state (undriven). In those - cases, the bits are floating, but will usually be the same as the - last data bus value (the 'usually' is emulated by randomly driving - certain bits high). - - However, some CMOS EPROM chips always drive Z-state bits high. - This is emulated by hmask, which specifies to push a specific - Z-state bit high. - - @param zmask The bits which are in Z-state - @param hmask The bits which should always be driven high - @return The data bus state - */ - uInt8 getDataBusState(uInt8 zmask, uInt8 hmask = 0x00) const - { - // For the pins that are floating, randomly decide which are high or low - // Otherwise, they're specifically driven high - return (myDataBusState | (randGenerator().next() | hmask)) & zmask; - } - /** Get the byte at the specified address. No masking of the address occurs before it's sent to the device mapped at diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 656524eae..6d3461c4c 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -414,85 +414,81 @@ uInt8 TIA::peek(uInt16 address) { updateEmulation(); - // If pins are undriven, we start with the last databus value - // Otherwise, there is some randomness injected into the mix - // In either case, we start out with D7 and D6 disabled (the only - // valid bits in a TIA read), and selectively enable them - uInt8 lastDataBusValue = - !myTIAPinsDriven ? mySystem->getDataBusState() : mySystem->getDataBusState(0xFF); - - uInt8 result; + // Start with all bits disabled + // In some cases both D7 and D6 are used; in other cases only D7 is used + uInt8 result = 0b0000000; switch (address & 0x0F) { case CXM0P: - result = collCXM0P(); + result = collCXM0P() & 0b11000000; break; case CXM1P: - result = collCXM1P(); + result = collCXM1P() & 0b11000000; break; case CXP0FB: - result = collCXP0FB(); + result = collCXP0FB() & 0b11000000; break; case CXP1FB: - result = collCXP1FB(); + result = collCXP1FB() & 0b11000000; break; case CXM0FB: - result = collCXM0FB(); + result = collCXM0FB() & 0b11000000; break; case CXM1FB: - result = collCXM1FB(); + result = collCXM1FB() & 0b11000000; break; case CXPPMM: - result = collCXPPMM(); + result = collCXPPMM() & 0b11000000; break; case CXBLPF: - result = collCXBLPF(); + result = collCXBLPF() & 0b10000000; break; case INPT0: updatePaddle(0); - result = myPaddleReaders[0].inpt(myTimestamp) | (lastDataBusValue & 0x40); + result = myPaddleReaders[0].inpt(myTimestamp) & 0b10000000; break; case INPT1: updatePaddle(1); - result = myPaddleReaders[1].inpt(myTimestamp) | (lastDataBusValue & 0x40); + result = myPaddleReaders[1].inpt(myTimestamp) & 0b10000000; break; case INPT2: updatePaddle(2); - result = myPaddleReaders[2].inpt(myTimestamp) | (lastDataBusValue & 0x40); + result = myPaddleReaders[2].inpt(myTimestamp) & 0b10000000; break; case INPT3: updatePaddle(3); - result = myPaddleReaders[3].inpt(myTimestamp) | (lastDataBusValue & 0x40); + result = myPaddleReaders[3].inpt(myTimestamp) & 0b10000000; break; case INPT4: - result = - myInput0.inpt(!myConsole.leftController().read(Controller::DigitalPin::Six)) | - (lastDataBusValue & 0x40); + result = myInput0.inpt(!myConsole.leftController().read(Controller::DigitalPin::Six)) + & 0b10000000; break; case INPT5: - result = - myInput1.inpt(!myConsole.rightController().read(Controller::DigitalPin::Six)) | - (lastDataBusValue & 0x40); + result = myInput1.inpt(!myConsole.rightController().read(Controller::DigitalPin::Six)) + & 0b10000000; break; default: - result = 0; + break; } - return (result & 0xC0) | (lastDataBusValue & 0x3F); + // Bits D5 .. D0 are floating + // The options are either to use the last databus value, or use random data + return result | ((!myTIAPinsDriven ? mySystem->getDataBusState() : + mySystem->randGenerator().next()) & 0b00111111); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 9f048706afb9efd6f7de3fdbc419378606dcbf91 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 17 Jun 2020 00:20:26 +0200 Subject: [PATCH 084/104] Fix reads and writes during timer wrap. Fixes #606 . --- src/emucore/M6532.cxx | 18 ++++++++---------- src/emucore/M6532.hxx | 3 +-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index f9eb8025c..18f950e62 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -59,7 +59,6 @@ void M6532::reset() myTimer = mySystem->randGenerator().next() & 0xff; myDivider = 1024; mySubTimer = 0; - myTimerWrapped = false; myWrappedThisCycle = false; mySetTimerCycle = myLastCycle = 0; @@ -121,16 +120,16 @@ void M6532::updateEmulation() myWrappedThisCycle = false; mySubTimer = (cycles + mySubTimer) % myDivider; - if(!myTimerWrapped) + if ((myInterruptFlag & TimerBit) == 0) { uInt32 timerTicks = (cycles + subTimer) / myDivider; if(timerTicks > myTimer) { cycles -= ((myTimer + 1) * myDivider - subTimer); + myWrappedThisCycle = cycles == 0; myTimer = 0xFF; - myTimerWrapped = true; myInterruptFlag |= TimerBit; } else @@ -140,8 +139,10 @@ void M6532::updateEmulation() } } - if(myTimerWrapped) + if((myInterruptFlag & TimerBit) != 0) { myTimer = (myTimer - cycles) & 0xFF; + myWrappedThisCycle = myTimer == 0xFF; + } myLastCycle = mySystem->cycles(); } @@ -219,7 +220,7 @@ uInt8 M6532::peek(uInt16 addr) { // Timer Flag is always cleared when accessing INTIM if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit; - myTimerWrapped = false; + return myTimer; } @@ -312,10 +313,9 @@ void M6532::setTimerRegister(uInt8 value, uInt8 interval) myTimer = value; mySubTimer = myDivider - 1; - myTimerWrapped = false; // Interrupt timer flag is cleared (and invalid) when writing to the timer - myInterruptFlag &= ~TimerBit; + if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit; mySetTimerCycle = mySystem->cycles(); } @@ -364,7 +364,6 @@ bool M6532::save(Serializer& out) const out.putInt(myTimer); out.putInt(mySubTimer); out.putInt(myDivider); - out.putBool(myTimerWrapped); out.putBool(myWrappedThisCycle); out.putLong(myLastCycle); out.putLong(mySetTimerCycle); @@ -397,7 +396,6 @@ bool M6532::load(Serializer& in) myTimer = in.getInt(); mySubTimer = in.getInt(); myDivider = in.getInt(); - myTimerWrapped = in.getBool(); myWrappedThisCycle = in.getBool(); myLastCycle = in.getLong(); mySetTimerCycle = in.getLong(); @@ -446,7 +444,7 @@ Int32 M6532::intimClocks() // INTIM value, it will give the current number of clocks between one // INTIM value and the next - return myTimerWrapped ? 1 : (myDivider - mySubTimer); + return ((myInterruptFlag & TimerBit) != 0) ? 1 : (myDivider - mySubTimer); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index 9aa4368b9..6e7408798 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -196,8 +196,7 @@ class M6532 : public Device // The divider uInt32 myDivider{1}; - // Has the timer wrapped? - bool myTimerWrapped{false}; + // Has the timer wrapped this very cycle? bool myWrappedThisCycle{false}; // Cycle when the timer set. Debugging only. From 1893a8f434d4563da6fe665edf21d7d7d381a84f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 17 Jun 2020 22:42:54 +0200 Subject: [PATCH 085/104] fixed crash in Audio & Video dialog when opened from debugger --- Changes.txt | 4 ++++ src/gui/VideoAudioDialog.cxx | 29 +++++++++++++---------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Changes.txt b/Changes.txt index 3e2c16150..6178d2d3e 100644 --- a/Changes.txt +++ b/Changes.txt @@ -33,6 +33,10 @@ * Fixed some bugs in 3E+ scheme when using non-standard ROM sizes. + * Fixed custom palette and TV effects adjustable slider rounding issue. + + * Fixed crash in Audio & Video dialog when opened from debugger. + * Updated documentation for changes in ROM properties key names. * The codebase now compiles under gcc6 again. Future versions will diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 23e7692cc..e87cbe221 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -1005,24 +1005,21 @@ void VideoAudioDialog::handleCommand(CommandSender* sender, int cmd, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void VideoAudioDialog::addPalette(int x, int y, int w, int h) { - if(instance().hasConsole()) - { - constexpr int NUM_LUMA = 8; - constexpr int NUM_CHROMA = 16; - const GUI::Font& ifont = instance().frameBuffer().infoFont(); - const int lwidth = ifont.getMaxCharWidth() * 1.5; - const float COLW = float(w - lwidth) / NUM_LUMA; - const float COLH = float(h) / NUM_CHROMA; - const int yofs = (COLH - ifont.getFontHeight() + 1) / 2; + constexpr int NUM_LUMA = 8; + constexpr int NUM_CHROMA = 16; + const GUI::Font& ifont = instance().frameBuffer().infoFont(); + const int lwidth = ifont.getMaxCharWidth() * 1.5; + const float COLW = float(w - lwidth) / NUM_LUMA; + const float COLH = float(h) / NUM_CHROMA; + const int yofs = (COLH - ifont.getFontHeight() + 1) / 2; - for(int idx = 0; idx < NUM_CHROMA; ++idx) + for(int idx = 0; idx < NUM_CHROMA; ++idx) + { + myColorLbl[idx] = new StaticTextWidget(myTab, ifont, x, y + yofs + idx * COLH, " "); + for(int lum = 0; lum < NUM_LUMA; ++lum) { - myColorLbl[idx] = new StaticTextWidget(myTab, ifont, x, y + yofs + idx * COLH, " "); - for(int lum = 0; lum < NUM_LUMA; ++lum) - { - myColor[idx][lum] = new ColorWidget(myTab, _font, x + lwidth + lum * COLW, y + idx * COLH, - COLW + 1, COLH + 1, 0, false); - } + myColor[idx][lum] = new ColorWidget(myTab, _font, x + lwidth + lum * COLW, y + idx * COLH, + COLW + 1, COLH + 1, 0, false); } } } From 8ca5684b67647998b79ec69dc43d8a03011c113a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 18 Jun 2020 07:22:47 +0200 Subject: [PATCH 086/104] simple fix for #667 (minimized window) --- src/gui/EmulationDialog.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/EmulationDialog.cxx b/src/gui/EmulationDialog.cxx index e9bb3804a..dcbb42859 100644 --- a/src/gui/EmulationDialog.cxx +++ b/src/gui/EmulationDialog.cxx @@ -237,6 +237,7 @@ void EmulationDialog::saveConfig() instance().console().initializeAudio(); // update VSync instance().console().initializeVideo(); + instance().createFrameBuffer(); instance().frameBuffer().tiaSurface().ntsc().enableThreading(myUseThreads->getState()); } From ef12cb49cc8502368806e4b1645ac9b29831a643 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 18 Jun 2020 12:06:29 -0230 Subject: [PATCH 087/104] Updated changelog, and bumped state number for recent changes in M6532 class. --- Changes.txt | 24 +++++++++++++++--------- src/common/StateManager.hxx | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Changes.txt b/Changes.txt index 6178d2d3e..490d98b82 100644 --- a/Changes.txt +++ b/Changes.txt @@ -16,15 +16,10 @@ * Fixed Pitfall II ROM not working correctly. - * A ROM properties file may now be placed next to the ROM (with the same - name as the ROM, except ending in .pro), and Stella will automatically - apply the properties to the ROM. [NOTE: this was present in 6.2, but - was mistakenly left out of the changelog] + * Fixed crashes when using some combinations of bankswitching schemes on + incorrect ROMs, or when using invalid ROM file sizes, etc. - * Make NTSC custom phase shift not affect Yellow anymore. - - * Allow changing custom palette and TV effects adjustables in 1% steps - again. + * Fixed RIOT timer behaviour on reading/writing at the wraparound cycle. * Fixed incorrectly setting D6 bit on TIA reads in some cases. Related to this, improve 'tiadriven' option to randomize only D5..D0 bits. @@ -35,7 +30,18 @@ * Fixed custom palette and TV effects adjustable slider rounding issue. - * Fixed crash in Audio & Video dialog when opened from debugger. + * Fixed crash in Audio & Video dialog when opened from debugger, and the + debugger window sometimes being resized when using the Options dialog. + + * Make NTSC custom phase shift not affect Yellow anymore. + + * A ROM properties file may now be placed next to the ROM (with the same + name as the ROM, except ending in .pro), and Stella will automatically + apply the properties to the ROM. [NOTE: this was present in 6.2, but + was mistakenly left out of the changelog] + + * Allow changing custom palette and TV effects adjustables in 1% steps + again. * Updated documentation for changes in ROM properties key names. diff --git a/src/common/StateManager.hxx b/src/common/StateManager.hxx index a69a48cd5..83f3d7acc 100644 --- a/src/common/StateManager.hxx +++ b/src/common/StateManager.hxx @@ -18,7 +18,7 @@ #ifndef STATE_MANAGER_HXX #define STATE_MANAGER_HXX -#define STATE_HEADER "06020000state" +#define STATE_HEADER "06020090state" class OSystem; class RewindManager; From 5d0084307bcb28e7215a3dd3569324bdb2cec5f4 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 18 Jun 2020 21:48:51 -0230 Subject: [PATCH 088/104] Fix TIA images saved in '1x' mode to not use TV effects (fixes #643). --- Changes.txt | 3 +++ src/debugger/gui/TiaOutputWidget.cxx | 2 +- src/emucore/TIASurface.cxx | 15 +-------------- src/emucore/TIASurface.hxx | 12 ++++++++---- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/Changes.txt b/Changes.txt index 490d98b82..2a5efe3b6 100644 --- a/Changes.txt +++ b/Changes.txt @@ -35,6 +35,9 @@ * Make NTSC custom phase shift not affect Yellow anymore. + * Fixed '1x' snapshot mode; TV effects are now disabled. This mode + now generates a clean, pixel-exact image. + * A ROM properties file may now be placed next to the ROM (with the same name as the ROM, except ending in .pro), and Stella will automatically apply the properties to the ROM. [NOTE: this was present in 6.2, but diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 5277647dc..01d6d094b 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -179,7 +179,7 @@ void TiaOutputWidget::drawWidget(bool hilite) bool visible = instance().console().tia().electronBeamPos(scanx, scany); scanoffset = width * scany + scanx; uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer(); - TIASurface& tiaSurface(instance().frameBuffer().tiaSurface()); + const TIASurface& tiaSurface = instance().frameBuffer().tiaSurface(); for(uInt32 y = 0, i = yStart * width; y < height; ++y) { diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index afaad7855..781ca203a 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -148,32 +148,19 @@ const FBSurface& TIASurface::baseSurface(Common::Rect& rect) const uInt32 tiaw = myTIA->width(), width = tiaw * 2, height = myTIA->height(); rect.setBounds(0, 0, width, height); - // Get Blargg buffer and width - uInt32 *blarggBuf, blarggPitch; - myTiaSurface->basePtr(blarggBuf, blarggPitch); - double blarggXFactor = double(blarggPitch) / width; - bool useBlargg = ntscEnabled(); - // Fill the surface with pixels from the TIA, scaled 2x horizontally uInt32 *buf_ptr, pitch; myBaseTiaSurface->basePtr(buf_ptr, pitch); for(uInt32 y = 0; y < height; ++y) - { for(uInt32 x = 0; x < width; ++x) - { - if (useBlargg) - *buf_ptr++ = blarggBuf[y * blarggPitch + uInt32(nearbyint(x * blarggXFactor))]; - else *buf_ptr++ = myPalette[*(myTIA->frameBuffer() + y * tiaw + x / 2)]; - } - } return *myBaseTiaSurface; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 TIASurface::mapIndexedPixel(uInt8 indexedColor, uInt8 shift) +uInt32 TIASurface::mapIndexedPixel(uInt8 indexedColor, uInt8 shift) const { return myPalette[indexedColor | shift]; } diff --git a/src/emucore/TIASurface.hxx b/src/emucore/TIASurface.hxx index 826ff75d9..2b6213785 100644 --- a/src/emucore/TIASurface.hxx +++ b/src/emucore/TIASurface.hxx @@ -70,14 +70,18 @@ class TIASurface void setPalette(const PaletteArray& tia_palette, const PaletteArray& rgb_palette); /** - Get the TIA base surface for use in saving to a PNG image. + Get a TIA surface that has no post-processing whatsoever. This is + currently used to save PNG image in the so-called '1x mode'. + + @param rect Specifies the area in which the surface data is valid */ const FBSurface& baseSurface(Common::Rect& rect) const; /** - Use the palette to map a single indexed pixel color. This is used by the TIA output widget. + Use the palette to map a single indexed pixel color. This is used by the + TIA output widget. */ - uInt32 mapIndexedPixel(uInt8 indexedColor, uInt8 shift = 0); + uInt32 mapIndexedPixel(uInt8 indexedColor, uInt8 shift = 0) const; /** Get the NTSCFilter object associated with the framebuffer @@ -220,7 +224,7 @@ class TIASurface bool mySaveSnapFlag{false}; // The palette handler - unique_ptrmyPaletteHandler; + unique_ptr myPaletteHandler; private: // Following constructors and assignment operators not supported From 7c91e2d60bd9188317268c6a6336075f8709d1ba Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 19 Jun 2020 22:31:29 +0200 Subject: [PATCH 089/104] fix missing key mapping when event version has changed --- src/common/PKeyboardHandler.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 4408081d7..4ff5191fb 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -39,6 +39,7 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& myHandler(handler) { Int32 version = myOSystem.settings().getInt("event_ver"); + bool updateDefaults = false; // Compare if event list version has changed so that key maps became invalid if (version == Event::VERSION) @@ -53,11 +54,12 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& myKeyMap.loadMapping(list, EventMode::kKeypadMode); list = myOSystem.settings().getString("keymap_ui"); myKeyMap.loadMapping(list, EventMode::kMenuMode); + updateDefaults = true; } myKeyMap.enableMod() = myOSystem.settings().getBool("modcombo"); - setDefaultMapping(Event::NoType, EventMode::kEmulationMode, true); - setDefaultMapping(Event::NoType, EventMode::kMenuMode, true); + setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults); + setDefaultMapping(Event::NoType, EventMode::kMenuMode, updateDefaults); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 6048fa9bc5df257f91b02114f0a1045070a55ba2 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jun 2020 19:55:27 -0230 Subject: [PATCH 090/104] Make sure long messages overlaid on framebuffer don't overflow display surface. --- src/emucore/FrameBuffer.cxx | 7 ++++--- src/emucore/FrameBuffer.hxx | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 4812e22f6..97af29fcf 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -513,7 +513,8 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, myMsg.text = message; myMsg.color = kBtnTextColor; myMsg.showGauge = false; - myMsg.w = font().getStringWidth(myMsg.text) + HBORDER * 2; + myMsg.w = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2, + font().getStringWidth(myMsg.text) + HBORDER * 2); myMsg.h = fontHeight + VBORDER * 2; myMsg.position = position; myMsg.enabled = true; @@ -533,7 +534,7 @@ void FrameBuffer::showMessage(const string& message, const string& valueText, return; const int fontWidth = font().getMaxCharWidth(), - fontHeight = font().getFontHeight(); + fontHeight = font().getFontHeight(); const int VBORDER = fontHeight / 4; const int HBORDER = fontWidth * 1.25 / 2.0; @@ -565,7 +566,7 @@ void FrameBuffer::showMessage(const string& message, const string& valueText, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBuffer::messageShown() +bool FrameBuffer::messageShown() const { #ifdef GUI_SUPPORT return myMsg.enabled; diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index b09d492f1..0a55a0f89 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -166,7 +166,7 @@ class FrameBuffer void showMessage(const string& message, const string& valueText, float value, float minValue = 0.F, float maxValue = 100.F); - bool messageShown(); + bool messageShown() const; /** Toggles showing or hiding framerate statistics. From 06db9b4f4a85d0044c6816d61154d86ffb75505f Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jun 2020 20:02:00 -0230 Subject: [PATCH 091/104] Remove superfluous 'deltax' parameter in drawString; I have no idea what it was doing there. --- src/emucore/FBSurface.cxx | 9 ++++----- src/emucore/FBSurface.hxx | 6 ++---- src/emucore/FrameBuffer.cxx | 6 +++--- src/gui/Widget.cxx | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index c489fc703..4b882346f 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -329,7 +329,7 @@ bool FBSurface::isWhiteSpace(const char s) const int FBSurface::drawString(const GUI::Font& font, const string& s, int x, int y, int w, int h, ColorId color, TextAlign align, - int deltax, bool useEllipsis, ColorId shadowColor) + bool useEllipsis, ColorId shadowColor) { int lines = 1; @@ -355,13 +355,13 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, //str += inStr[i]; } wrapString(inStr, i, leftStr, rightStr); - drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor); + drawString(font, leftStr, x, y, w, color, align, false, shadowColor); h -= font.getFontHeight(); y += font.getFontHeight(); inStr = rightStr; lines++; } - drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor); + drawString(font, inStr, x, y, w, color, align, useEllipsis, shadowColor); #endif return lines; } @@ -370,7 +370,7 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, void FBSurface::drawString(const GUI::Font& font, const string& s, int x, int y, int w, ColorId color, TextAlign align, - int deltax, bool useEllipsis, ColorId shadowColor) + bool useEllipsis, ColorId shadowColor) { #ifdef GUI_SUPPORT const string ELLIPSIS = "\x1d"; // "..." @@ -410,7 +410,6 @@ void FBSurface::drawString(const GUI::Font& font, const string& s, else if(align == TextAlign::Right) x = x + w - width; - x += deltax; for(i = 0; i < str.size(); ++i) { w = font.getCharWidth(str[i]); diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 48632404d..4be99dc42 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -218,7 +218,6 @@ class FBSurface @param h The height of the string area (for multi line strings) @param color The color of the text @param align The alignment of the text in the string width area - @param deltax FIXME @param useEllipsis Whether to use '...' when the string is too long @return Number of lines drawn */ @@ -226,7 +225,7 @@ class FBSurface virtual int drawString( const GUI::Font& font, const string& s, int x, int y, int w, int h, ColorId color, TextAlign align = TextAlign::Left, - int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); + bool useEllipsis = true, ColorId shadowColor = kNone); /** This method should be called to draw the specified string. @@ -238,13 +237,12 @@ class FBSurface @param w The width of the string area @param color The color of the text @param align The alignment of the text in the string width area - @param deltax FIXME @param useEllipsis Whether to use '...' when the string is too long */ virtual void drawString( const GUI::Font& font, const string& s, int x, int y, int w, ColorId color, TextAlign align = TextAlign::Left, - int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); + bool useEllipsis = true, ColorId shadowColor = kNone); ////////////////////////////////////////////////////////////////////////// // Note: The following methods are FBSurface-specific, and must be diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 97af29fcf..2a53d2c8f 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -600,7 +600,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) << info.DisplayFormat; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); + myStatsMsg.w, color, TextAlign::Left, true, kBGColor); yPos += dy; ss.str(""); @@ -615,7 +615,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) << "% speed"; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, true, kBGColor); yPos += dy; ss.str(""); @@ -624,7 +624,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) if (myOSystem.settings().getBool("dev.settings")) ss << "| Developer"; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, true, kBGColor); myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8); myStatsMsg.surface->setDstSize(myStatsMsg.w * hidpiScaleFactor(), diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index ed6ba2f02..132bbd7b9 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -344,7 +344,7 @@ void StaticTextWidget::drawWidget(bool hilite) FBSurface& s = _boss->dialog().surface(); bool onTop = _boss->dialog().isOnTop(); s.drawString(_font, _label, _x, _y, _w, - isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor); + isEnabled() && onTop ? _textcolor : kColor, _align, true, _shadowcolor); setDirty(); } From 1bfcac8a6e348f2539750c0f19b3ebc3879b3fc0 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jun 2020 20:07:07 -0230 Subject: [PATCH 092/104] Added 'Save' button to GameInfoDialog, to save current properties to a separate .pro file. --- Changes.txt | 4 ++++ src/gui/Dialog.cxx | 28 ++++++++++++++++++++++++++ src/gui/Dialog.hxx | 9 +++++++++ src/gui/GameInfoDialog.cxx | 41 +++++++++++++++++++++++++++++++++----- src/gui/GameInfoDialog.hxx | 6 ++++++ 5 files changed, 83 insertions(+), 5 deletions(-) diff --git a/Changes.txt b/Changes.txt index 2a5efe3b6..9fa3661e9 100644 --- a/Changes.txt +++ b/Changes.txt @@ -43,6 +43,10 @@ apply the properties to the ROM. [NOTE: this was present in 6.2, but was mistakenly left out of the changelog] + * Added button to Game Info dialog to save properties of the currently + loaded ROM to a separate properties file (in the default save directory). + This is useful in conjunction with the previous item. + * Allow changing custom palette and TV effects adjustables in 1% steps again. diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 1cc0b3b8c..e455a976c 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -835,6 +835,34 @@ void Dialog::addDefaultsOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, addOKCancelBGroup(wid, font, okText, cancelText, focusOKButton, buttonWidth); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::addDefaultsExtraOKCancelBGroup( + WidgetArray& wid, const GUI::Font& font, + const string& extraText, int extraCmd, + const string& okText, const string& cancelText, const string& defaultsText, + bool focusOKButton) +{ + const int fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int BTN_BORDER = fontWidth * 2.5; + const int BUTTON_GAP = fontWidth; + const int buttonWidth = font.getStringWidth(defaultsText) + BTN_BORDER; + + addDefaultWidget(new ButtonWidget(this, font, HBORDER, _h - buttonHeight - VBORDER, + buttonWidth, buttonHeight, defaultsText, GuiObject::kDefaultsCmd)); + wid.push_back(_defaultWidget); + + wid.push_back(new ButtonWidget(this, font, HBORDER + buttonWidth + BUTTON_GAP, + _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, + extraText, extraCmd) + ); + + addOKCancelBGroup(wid, font, okText, cancelText, focusOKButton, buttonWidth); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::TabFocus::appendFocusList(WidgetArray& list) { diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 5b95fe5e0..0dc5e7118 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -158,6 +158,15 @@ class Dialog : public GuiObject const string& defaultsText = "Defaults", bool focusOKButton = true); + // NOTE: This method, and the two above it, are due to be refactored at some + // point, since the parameter list is kind of getting ridiculous + void addDefaultsExtraOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, + const string& extraText, int extraCmd, + const string& okText = "OK", + const string& cancelText = "Cancel", + const string& defaultsText = "Defaults", + bool focusOKButton = true); + void processCancelWithoutWidget(bool state) { _processCancel = state; } virtual void processCancel() { close(); } diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index fd646c6ed..2348e047d 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -383,7 +383,7 @@ GameInfoDialog::GameInfoDialog( // Add Defaults, OK and Cancel buttons wid.clear(); - addDefaultsOKCancelBGroup(wid, font); + addDefaultsExtraOKCancelBGroup(wid, font, "Save", kSavePressed); addBGroupToFocusList(wid); } @@ -393,11 +393,13 @@ void GameInfoDialog::loadConfig() if(instance().hasConsole()) { myGameProperties = instance().console().properties(); + myGameFile = instance().romFile(); } else { const string& md5 = instance().launcher().selectedRomMD5(); instance().propSet().getMD5(md5, myGameProperties); + myGameFile = FilesystemNode(instance().launcher().selectedRom()); } loadEmulationProperties(myGameProperties); @@ -568,7 +570,7 @@ void GameInfoDialog::loadCartridgeProperties(const Properties& props) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void GameInfoDialog::saveConfig() +void GameInfoDialog::saveProperties() { // Emulation properties myGameProperties.set(PropType::Cart_Type, myBSType->getSelectedTag().toString()); @@ -613,6 +615,12 @@ void GameInfoDialog::saveConfig() myGameProperties.set(PropType::Cart_ModelNo, myModelNo->getText()); myGameProperties.set(PropType::Cart_Rarity, myRarity->getText()); myGameProperties.set(PropType::Cart_Note, myNote->getText()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void GameInfoDialog::saveConfig() +{ + saveProperties(); // Always insert; if the properties are already present, nothing will happen instance().propSet().insert(myGameProperties); @@ -626,7 +634,7 @@ void GameInfoDialog::saveConfig() // update 'Emulation' tab settings immediately instance().console().setFormat(myFormat->getSelected()); instance().frameBuffer().tiaSurface().enablePhosphor(myPhosphor->getState(), myPPBlend->getValue()); - instance().console().updateVcenter(vcenter); + instance().console().updateVcenter(myVCenter->getValue()); instance().console().initializeAudio(); // update 'Console' tab settings immediately @@ -782,19 +790,38 @@ void GameInfoDialog::eraseEEPROM() Controller& lport = instance().console().leftController(); Controller& rport = instance().console().rightController(); - if(lport.type() == Controller::Type::SaveKey || lport.type() == Controller::Type::AtariVox) + if(lport.type() == Controller::Type::SaveKey || + lport.type() == Controller::Type::AtariVox) { SaveKey& skey = static_cast(lport); skey.eraseCurrent(); } - if(rport.type() == Controller::Type::SaveKey || rport.type() == Controller::Type::AtariVox) + if(rport.type() == Controller::Type::SaveKey || + rport.type() == Controller::Type::AtariVox) { SaveKey& skey = static_cast(rport); skey.eraseCurrent(); } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void GameInfoDialog::saveCurrentPropertiesToDisk() +{ + saveProperties(); + + FilesystemNode propfile(instance().defaultSaveDir() + myGameFile.getNameWithExt(".pro")); + ofstream out(propfile.getPath()); + if(out) + { + out << myGameProperties; + instance().frameBuffer().showMessage("Properties saved to " + + propfile.getShortPath()); + } + else + instance().frameBuffer().showMessage("Error saving properties"); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) @@ -810,6 +837,10 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, setDefaults(); break; + case kSavePressed: + saveCurrentPropertiesToDisk(); + break; + case TabWidget::kTabChangedCmd: if(data == 2) // 'Controllers' tab selected updateControllerStates(); diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index 2e2dc4f8a..7e5febdde 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -53,9 +53,12 @@ class GameInfoDialog : public Dialog, public CommandSender void loadControllerProperties(const Properties& props); // load the properties for the 'Cartridge' tab void loadCartridgeProperties(const Properties& props); + // save properties from all tabs into the local properties object + void saveProperties(); void updateControllerStates(); void eraseEEPROM(); + void saveCurrentPropertiesToDisk(); private: TabWidget* myTab{nullptr}; @@ -115,10 +118,13 @@ class GameInfoDialog : public Dialog, public CommandSender kEEButtonPressed = 'EEgb', kPXCenterChanged = 'Pxch', kPYCenterChanged = 'Pych', + kSavePressed = 'GIsp' }; // Game properties for currently loaded ROM Properties myGameProperties; + // Filename of the currently loaded ROM + FilesystemNode myGameFile; private: // Following constructors and assignment operators not supported From 464111c39d0fff553e70e67cca5e5a478ae2bc13 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jun 2020 20:20:56 -0230 Subject: [PATCH 093/104] Updated various files for 6.2.1 release. --- Announce.txt | 22 +++++++++++----------- Changes.txt | 6 +++--- debian/changelog | 7 +++++++ docs/debugger.html | 2 +- docs/index.html | 2 +- docs/index_r77.html | 2 +- src/common/StateManager.hxx | 2 +- src/common/Version.hxx | 4 ++-- src/macos/Info-Stella.plist | 4 ++-- src/unix/stella.spec | 5 ++++- src/windows/stella.rc | 8 ++++---- 11 files changed, 37 insertions(+), 27 deletions(-) diff --git a/Announce.txt b/Announce.txt index 6b85d8d00..2262f7975 100644 --- a/Announce.txt +++ b/Announce.txt @@ -9,7 +9,7 @@ SSSS ttt eeeee llll llll aaaaa =========================================================================== - Release 6.2 for Linux, macOS and Windows + Release 6.2.1 for Linux, macOS and Windows =========================================================================== The Atari 2600 Video Computer System (VCS), introduced in 1977, was the @@ -21,27 +21,27 @@ all of your favourite Atari 2600 games again! Stella was originally developed for Linux by Bradford W. Mott, however, it has been ported to a number of other platforms and is currently maintained by Stephen Anthony. -This is the 6.2 release of Stella for Linux, macOS and Windows. The +This is the 6.2.1 release of Stella for Linux, macOS and Windows. The distributions currently available are: * Binaries for Windows Vista/7/8/10 : - Stella-6.2-win32.exe (32-bit EXE installer) - Stella-6.2-x64.exe (64-bit EXE installer) - Stella-6.2-windows.zip (32/64 bit versions) + Stella-6.2.1-win32.exe (32-bit EXE installer) + Stella-6.2.1-x64.exe (64-bit EXE installer) + Stella-6.2.1-windows.zip (32/64 bit versions) * Binary distribution for macOS 10.7 and above : - Stella-6.2-macos.dmg (64-bit Intel) + Stella-6.2.1-macos.dmg (64-bit Intel) * Binary distribution in 32-bit & 64-bit Ubuntu DEB format : - stella_6.2-1_i386.deb - stella_6.2-1_amd64.deb + stella_6.2.1-1_i386.deb + stella_6.2.1-1_amd64.deb * Binary distribution in 32-bit & 64-bit RPM format : - stella-6.2-2.i386.rpm - stella-6.2-2.x86_64.rpm + stella-6.2.1-2.i386.rpm + stella-6.2.1-2.x86_64.rpm * Source code distribution for all platforms : - stella-6.2-src.tar.xz + stella-6.2.1-src.tar.xz Distribution Site diff --git a/Changes.txt b/Changes.txt index 9fa3661e9..749085128 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,7 +12,7 @@ Release History =========================================================================== -6.2 to 6.2.1: (XXX xx, 2020) +6.2 to 6.2.1: (June 20, 2020) * Fixed Pitfall II ROM not working correctly. @@ -28,8 +28,6 @@ * Fixed some bugs in 3E+ scheme when using non-standard ROM sizes. - * Fixed custom palette and TV effects adjustable slider rounding issue. - * Fixed crash in Audio & Video dialog when opened from debugger, and the debugger window sometimes being resized when using the Options dialog. @@ -38,6 +36,8 @@ * Fixed '1x' snapshot mode; TV effects are now disabled. This mode now generates a clean, pixel-exact image. + * Fixed mappings sometimes not being saved in the Retron77 port. + * A ROM properties file may now be placed next to the ROM (with the same name as the ROM, except ending in .pro), and Stella will automatically apply the properties to the ROM. [NOTE: this was present in 6.2, but diff --git a/debian/changelog b/debian/changelog index 6b4dff642..75c7267b6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stella (6.2.1-1) stable; urgency=high + + * Version 6.2.1 release + + -- Stephen Anthony Sat, 20 Jun 2020 17:09:59 -0230 + + stella (6.2-1) stable; urgency=high * Version 6.2 release diff --git a/docs/debugger.html b/docs/debugger.html index 7f2cabec5..306885c34 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -15,7 +15,7 @@
Stella
-

Release 6.2

+

Release 6.2.1

Integrated Debugger

(a work in progress)


diff --git a/docs/index.html b/docs/index.html index 85d019040..5b711a86d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -19,7 +19,7 @@

A multi-platform Atari 2600 VCS emulator

-

Release 6.2

+

Release 6.2.1



User's Guide

diff --git a/docs/index_r77.html b/docs/index_r77.html index 33e767c7e..cc15b11ab 100644 --- a/docs/index_r77.html +++ b/docs/index_r77.html @@ -58,7 +58,7 @@

Stella for RetroN 77

Atari 2600 VCS emulator

-
Release 6.2
+
Release 6.2.1

Quick Navigation Guide


diff --git a/src/common/StateManager.hxx b/src/common/StateManager.hxx index 83f3d7acc..efb9286cb 100644 --- a/src/common/StateManager.hxx +++ b/src/common/StateManager.hxx @@ -18,7 +18,7 @@ #ifndef STATE_MANAGER_HXX #define STATE_MANAGER_HXX -#define STATE_HEADER "06020090state" +#define STATE_HEADER "06020100state" class OSystem; class RewindManager; diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 2c770f57f..b0e339035 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.2.1_pre" -#define STELLA_BUILD "6001" +#define STELLA_VERSION "6.2.1" +#define STELLA_BUILD "6039" #endif diff --git a/src/macos/Info-Stella.plist b/src/macos/Info-Stella.plist index 386e378fc..d9eb7520e 100644 --- a/src/macos/Info-Stella.plist +++ b/src/macos/Info-Stella.plist @@ -45,7 +45,7 @@ CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion - 6.2 + 6.2.1 CFBundleName Stella CFBundlePackageType @@ -53,7 +53,7 @@ CFBundleSignature StLa CFBundleVersion - 6.2 + 6.2.1 LSApplicationCategoryType public.app-category.games LSMinimumSystemVersionByArchitecture diff --git a/src/unix/stella.spec b/src/unix/stella.spec index 264b4da7e..c54cf259a 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -1,5 +1,5 @@ %define name stella -%define version 6.2 +%define version 6.2.1 %define rel 1 %define enable_sound 1 @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version} %_datadir/icons/large/%{name}.png %changelog +* Sat Jun 20 2020 Stephen Anthony 6.2.1-1 +- Version 6.2.1 release + * Sun Jun 7 2020 Stephen Anthony 6.2-1 - Version 6.2 release diff --git a/src/windows/stella.rc b/src/windows/stella.rc index 7facd2292..0958a136d 100755 --- a/src/windows/stella.rc +++ b/src/windows/stella.rc @@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,2,0,0 - PRODUCTVERSION 6,2,0,0 + FILEVERSION 6,2,1,0 + PRODUCTVERSION 6,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -55,12 +55,12 @@ BEGIN VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2." VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)" VALUE "FileDescription", "Stella" - VALUE "FileVersion", "6.2" + VALUE "FileVersion", "6.2.1" VALUE "InternalName", "Stella" VALUE "LegalCopyright", "Copyright (c) 1995-2020 The Stella Team" VALUE "OriginalFilename", "Stella.exe" VALUE "ProductName", "Stella" - VALUE "ProductVersion", "6.2" + VALUE "ProductVersion", "6.2.1" END END BLOCK "VarFileInfo" From 386d591e0846e6e826b551910e9396afb953d41a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jun 2020 20:25:00 -0230 Subject: [PATCH 094/104] Revert "Remove superfluous 'deltax' parameter in drawString; I have no idea what it was doing there." This reverts commit 06db9b4f4a85d0044c6816d61154d86ffb75505f. And as soon as I committed it, I suspected it would cause problems :( --- src/emucore/FBSurface.cxx | 9 +++++---- src/emucore/FBSurface.hxx | 6 ++++-- src/emucore/FrameBuffer.cxx | 6 +++--- src/gui/Widget.cxx | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index 4b882346f..c489fc703 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -329,7 +329,7 @@ bool FBSurface::isWhiteSpace(const char s) const int FBSurface::drawString(const GUI::Font& font, const string& s, int x, int y, int w, int h, ColorId color, TextAlign align, - bool useEllipsis, ColorId shadowColor) + int deltax, bool useEllipsis, ColorId shadowColor) { int lines = 1; @@ -355,13 +355,13 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, //str += inStr[i]; } wrapString(inStr, i, leftStr, rightStr); - drawString(font, leftStr, x, y, w, color, align, false, shadowColor); + drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor); h -= font.getFontHeight(); y += font.getFontHeight(); inStr = rightStr; lines++; } - drawString(font, inStr, x, y, w, color, align, useEllipsis, shadowColor); + drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor); #endif return lines; } @@ -370,7 +370,7 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, void FBSurface::drawString(const GUI::Font& font, const string& s, int x, int y, int w, ColorId color, TextAlign align, - bool useEllipsis, ColorId shadowColor) + int deltax, bool useEllipsis, ColorId shadowColor) { #ifdef GUI_SUPPORT const string ELLIPSIS = "\x1d"; // "..." @@ -410,6 +410,7 @@ void FBSurface::drawString(const GUI::Font& font, const string& s, else if(align == TextAlign::Right) x = x + w - width; + x += deltax; for(i = 0; i < str.size(); ++i) { w = font.getCharWidth(str[i]); diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 4be99dc42..48632404d 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -218,6 +218,7 @@ class FBSurface @param h The height of the string area (for multi line strings) @param color The color of the text @param align The alignment of the text in the string width area + @param deltax FIXME @param useEllipsis Whether to use '...' when the string is too long @return Number of lines drawn */ @@ -225,7 +226,7 @@ class FBSurface virtual int drawString( const GUI::Font& font, const string& s, int x, int y, int w, int h, ColorId color, TextAlign align = TextAlign::Left, - bool useEllipsis = true, ColorId shadowColor = kNone); + int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); /** This method should be called to draw the specified string. @@ -237,12 +238,13 @@ class FBSurface @param w The width of the string area @param color The color of the text @param align The alignment of the text in the string width area + @param deltax FIXME @param useEllipsis Whether to use '...' when the string is too long */ virtual void drawString( const GUI::Font& font, const string& s, int x, int y, int w, ColorId color, TextAlign align = TextAlign::Left, - bool useEllipsis = true, ColorId shadowColor = kNone); + int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); ////////////////////////////////////////////////////////////////////////// // Note: The following methods are FBSurface-specific, and must be diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 2a53d2c8f..97af29fcf 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -600,7 +600,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) << info.DisplayFormat; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, color, TextAlign::Left, true, kBGColor); + myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); yPos += dy; ss.str(""); @@ -615,7 +615,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) << "% speed"; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, true, kBGColor); + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); yPos += dy; ss.str(""); @@ -624,7 +624,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) if (myOSystem.settings().getBool("dev.settings")) ss << "| Developer"; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, true, kBGColor); + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8); myStatsMsg.surface->setDstSize(myStatsMsg.w * hidpiScaleFactor(), diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 132bbd7b9..ed6ba2f02 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -344,7 +344,7 @@ void StaticTextWidget::drawWidget(bool hilite) FBSurface& s = _boss->dialog().surface(); bool onTop = _boss->dialog().isOnTop(); s.drawString(_font, _label, _x, _y, _w, - isEnabled() && onTop ? _textcolor : kColor, _align, true, _shadowcolor); + isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor); setDirty(); } From 1cbdb810a9e3d68447e07444f98554c499eeb0d4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 20 Jun 2020 08:37:50 +0200 Subject: [PATCH 095/104] updated screenshots --- docs/graphics/options_gameinfo_cartridge.png | Bin 5210 -> 3168 bytes docs/graphics/options_gameinfo_console.png | Bin 4558 -> 2540 bytes docs/graphics/options_gameinfo_controller.png | Bin 4057 -> 4139 bytes docs/graphics/options_gameinfo_emulation.png | Bin 3393 -> 3476 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/graphics/options_gameinfo_cartridge.png b/docs/graphics/options_gameinfo_cartridge.png index ea09b98420e16a559dc4ccbe566fac9f2a17e7ee..b90761623b49600452ce6424dffe64eee68f17ec 100644 GIT binary patch literal 3168 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%0Db?EX1Q5of?%G2Uitol#9NfLfM(Mo}L zW8v40+>qEY>CDdM0rj3<%F(;!`z3s}J{-YxKEhqqWj0boquenj`;=uif%Cet87Y!} zLlR+9y``n5GA8OK99-{+IMx_Xq7@!~Q_*sW3ffsm1F^^P;hlCdxI_$sTbZatmxD@l-{jsZp8AIu#0rBz8Rb?D}M} zgJaw>v$mw$X*eW}r_$jLk6UF8_VIIn<{}5(wZ@iqlZ%S~}`F&XV#7~KeBqzC6qsmopM_te} zT+X_|QCKs*T@Z(EWwT zP&_LyRxpeOB>K>9+U>Z5zO|DJJ*WdsugHW*690q0@Y)~KwHmUA0wZJsn3k!B5f7aA zy}k%l7#Gy-SbVCN*AlPHZGAPWfW~w^o0?)*D{5V3I+{VvbjR}bhpU^%-C1^~U z^gn}UMnm06OwGZiomHTFk(xy+^wBWp{CIN@ZwJVqw8V@#BxS8&~kg*Z3pKW)JXJT&Dg zwQ!4}U8v`fHHvU%7U(6@acASbm4Iq*>q_w!9w{$aA`vyyz-7nSLCSf9Np+jDd86p! zG0G7uY7uJi8Lu_Qc4KU^BWTlysTZyX*Db%!TVY^vMLKHwrl0k1*N6XSyx|2N zQV0~*#nV3$#@RX_lYR&3z2*N-#At&y;JH1o>W!FAuUo-P%Z*`W1bZ331=;QC&{?PB z>uRBSru-oy1HF_(C234;BLOv!O!|13k-n?iKy+JWN?+V9Q}D%%rGL2$u4u5d7s|!U zAXQDu#{kpAJLiGft=rF*Y($M+;wJPi0+!h5T+4B|DvhBgZOl(26+^moF`@od5YIcG z*HfOp9uxFj9wjAdH4|)2`YA5ZXv_A4akYS8QE6lh4&kL87vZG^L+%-|U6Q>p~%c6z6ipF~e zF@5|*&bXvqQr2SVqVGx)z!qLiFa46D7J$+IjS>39lGD!fo3$iVDrg2OeyPa3bg|GJ zZob`UnPatXBl3a{G~$;1{+rRzS)(nkUvP+w_6$;1F?V#g5i@XX$3fKM7*^q{Mv@&E zaqM?IElu(2)9&m;WvZ>XeL~660nQM>c@YUb)T6m*H>zHU=EPx65%R6XU2p57MhI~7 z4-Og=4Gz<&Lvzn9+dgQQCo6%XXN+j6kDRV+76fFMRX}0fKBtiPj7F=G9MRy4V^V@F z1mr_+BgwD>^{{xDOZE=SA8W`z($?MmP=)W_gbU!>V`n<5JMjxs`j+PnYv;=%NeP*F z>3;u6^xq5>Bq78J5j&oS!=-34D1xMC z4{PUUO!2(5DVoGlWgF7-EBmJiQ#75`Ru#%V&@>C$RETkvm8wFr)3l)3?V>(R=6Av) zQq^n!?-CD434aGh+5iWV95`Ev&%ODj8UA5{KMnEk`~R{74-kiZVM;jg)?ZcKf66-! zyTcBSj$UVMT{u%n+^&1b3e}#pXA162$riL$$IuffIs}R@fx?ap6I`UKEc!4YI@#<$ zQAM6^hW+J@;FmE+IuCg&?wuRj>N*`Ri4L+W>&1ft8(*LQKuWfh>6QzDi-v9d~ z=9@$^Zcf+^{>PLq7Z|v3L>Q*5I6DRmB)1uhFoyAJf-u+mUjmy7x?e2${KzX4@}2qC za6%mqt1Nhb`LSKVcwUvqR9^g;c`8mi{hW|5X8YFcZ#=w8%3F;`&w4J(B*6CG7%Wq_ zI|Efd_;5#CYS*krlM>SztD;@ktly^?vV#W)n(s47?a4l_U5|bhMh5?6FfXt4FqjH~ zaTks(`}`<%7V^QX`13?3Tx$_RV@`e2MnqTcT=$a^Pau74%aik+8GY}Z!+vUCtk4at~vnrpZ^iIGi4-57>{;YGH0)u#OH8IR@k( z2LcI{SqL~v2VPmEdhFc<`3k{3>95VQTC$%H7bfW!m}zeLzu_vHRx5Qy9Eq64Xa9=Z TnU?(dm&ZWwrf#jaL)3o(-PS+I diff --git a/docs/graphics/options_gameinfo_console.png b/docs/graphics/options_gameinfo_console.png index 49577140c0a3b9038165da3df9efaf9005361709..e3aee16e58a7ec8a47ed7d3c318120ad6ba2b3a8 100644 GIT binary patch literal 2540 zcmd5;`#%#38z0fd-LW_-oOH^iIxeG~8Fi54S}vP2mslYS?ZS=19eBNK)^AEhw=kt7?&-eTM^xU81tB%&PQb(i!0D!E` z<%`Y$fY`i9JtX#t7}XCct|B8A?rd!Vs2x7GC;}2Fa|d$(pgvt%h?Epz{j2t_Rw5f1 z7+7tj&<6mFAv9 z31h2VvXk{R7Tz0d=vZiBb}YQ5L&ZVz_eqJrf(Wy@)BY~JtGNh2u=ll6FAyz_Y22v2 zq02n8>jAV#x}>IE;hncZuB%wJA|J&5#4PvQ?qzHH-Dg0^JMMqZNRB}+Wk8+Z7kTIzGsa<&#Q6#$g3KGGy^u{SNZa9g0xJrn2~_#` zBG~mO7gVgKib5WFZK8~|oLapCwI)zGgF&4>)8jhiWf_4Q?Ep{}U8Izuejjq!nzH~T zVw1GiG>pNb5ZX;0zCEU?3k+2NN1 zOfv=$=8*2!>WK>7Z87OnSsXpA8Xz^jN53UGLBtQ>?b>80tLQ9P|I~2JU;*r5kh8!7 z#YKi8>pI1|h!D(hcvX(7&vWw*xz;5~_8SU+V$~}YB%fD$-Z}9nUtU8U- zv&t~Kxj-=<7-0a{7vv~;`0_B;7WD`%$K%-?b*K6^x$m~IGwlMD(;cmI5A62YkV)&8 zksl#6dQ>UCl_BD~`TAF~ALF;2tCL+Hs>RL!sAgCc0unxX{+PS!$w_5Fn$sY5cupZO z>OtH#mc;A;s&8ib?5A8;-t?|j_839)e7`6Vu?HEZ5*+_^lS&+{V|ehdh>fGmRf6~1 z0v3ygqco=!w6#gEU?p)UFtwlZ)MS@`n_t{rJy%y@8PE*38BJu~AT z&2<*oPTR&_%h(n?^NabWoI`;@2j{UT8(8{5IeFU5xo@^a_BFD*Fw~pshobW^n!M$U za8gA9|3iXFc_7KaHz9!pla3oIU$o^N`wSbvQT-OCAYtA1MuWp%oE+nL2rVb_1%-?K z8nWBuc)n_O@0Bss?OfAsk5q6f>v?~EHy;KM@Wr*Pg#;Hwr45<6jq8U;fYz4YoAqM& zH&H)a(VD)XccNN0z4*r>|Blnc;M?fy7R^TJoY#2p>Ce+c**&8xko(95}~r>$(2kulEb^3A?jl%q>B$& z`&%(u`RB_fw=sO#Sq-Q!K9T74uSQ)<^tJ5+K($W|n**5fa|hYR`ekbM+OK~5AiO`9 zzyKNw=xJ6RlqJL9q8hFDSlzX!U7m;w$)`P-!#AWkhIoyAEtut+6|o~+W?9AP4&~4W z#@6?A6xA`7np3liAYbx^hC(IGLR|u{3f^en8IX*G${H-Ot9+(6a%wtE-JBlNIfZ8T zf*EEg-AN~nCi?GKL9`AOHMwX*-2C}_=CB8skkU7_mXIl2s~B?7k8NIe&Mq*NcYN>T5#@$Bt4-2N(awg z30|-qi@qMQ%VR|7QTDo4caZLhlcD009^z0`>kfhpx7f$Ih2)##g!vcGW@*gEztAG$ zZ{k#A@OHb=E}h4W;-cz`u63oj zUyjIXDB9w;?>A#`6a63MP_fo4tWfFXASGZR;YNR9CA-&!yg!gBE!FyLXZN0cO#76bkQzpt`sU!Emd<)=&OV2S!bXw#*s2xQ*hdVQqPnTvW)?Te zgl{OfMGLxyPL;SO&BQeR-MQ6?XMgTS2Rosfm5}hHnbsHnYNS?J!J^cgO8m3;|FdoWKjgWdVaUcay>Sks8UbRMQNkZ!?Z01q z5GxG2rW4y^q&K*K0*5#xIx+t(dh46y$By262l91wypt5e4t)Q;Y^)qF)>`;H_%|Zb B^^O1l literal 4558 zcmeHKXH*kgyAIM0Du`4;M5Kw3fYJnMQj`vgv=C|_5DB1wN>xbBjd8}R`eT#zlFXI1m7$4nciXY&^FbEKnMwkXfDhU2qWZ* ziRC3ajz*(#ikzJg$Piq+Al{{`EOflDXmz!ZKJ?G^4+H&zH;Ucp4>pE++LnQi%ULlQVP2V_w0PUHExwnRP0YvGTv z=tQiZdEp7Jo97RKdn&1|^`A1sXLw;_Zs|8gpif#y>zT%T+WV;AN8wz%$vR&zav$;K z;+lv(;F2!x%bqahLxEwCPWIPxW205Bb0a05w5p}vVfm6ruwOYh;m*E=;_Z0hD9c8r zEF8Ehk2UBT1@6~ghoxoWsf)1^IG8BK!2Y(1U-{`BeU43$*$+~-njFv- zG1d?++Ybyt0wcKF*@R^R0`6018`m}c$^j>4LnmM7GtiZOJA6Q;NM%&%1;T*noHP5- zmNoWd$HRy2gv5j_LYYO*BMmME}ywru})E#KCQ^VjVi#vU6=#eO}fj5OQ z(WH_B$-%r7R`M}b+g69vcuCYDSrA&~CWz2527lC~6vu3N;fTs`c%5eu;qk#ZBLVS6 z{xzx2wsCTIA4-rKSFdW|_BvJ)RhY7coVW{0;!UNk33kP|pwP0cIAx4su-$;QLRxN| zat_reTbZ9%(6fJq^H|N(+L2&@8Yg2v-+7DI5MA8FrOm;2&PuYE9T?+2EnzVCcn zqQbH0_8mvU*zF9MG|8;NxSuRQpHKBh5FAc|9;GvUwcxS$5JLV@DfToL)m*6rrUZ&8 zA}m9*Uu;Um+xJY=VQQ|!n;6AdF(o!H*p3ME!Afo4i2m>4)?;akNPrRjHFUW)Gy5+i}k@k@9HgIcM{H;Io(Fw6-on6n74b{GPh>+?{t+{;sb)JHT8~D@JJ9aL&M)4bD=@_`6ttiIl;%xA7RTUq9W@GX?K$ zl zXQjut-BgrX-B6*0C@K&*-n{(IGD($P=~KWT=4;JRK zo;4=RSTxdO2NX$WoUxMZcTg#3+8eB?>5?DHVeDHE$*Ss6x;|u(9^G-1ELo$$ zpjwBGw5m$X@CNr~ZzRN?2lG}xP2j?u_{fVZv7NRby^G=%r{J2VA&gqOo4f65Sv57z zL2C=&)W3?aSDI{W(8uCNe|)Mu{9)>y%vMLxzF})6?MJKmmi-So1y@^^6^37g9(LP_ zPGnPQISYi{`{r;ou)a|WX!C6|Q>n{=7YmSA-+yCvMNs-poP(M~fN;0>he7@HHu)pv zb-lyD^2drJTeUn>ChO3abyL;St{Zu)g9fBf%;mPRw*AJxc@kN)gx$G zep}0+%@l!*(`}wTu&2_eP0>7RX}fgs4t)Er`*wGv>E$UR)uIBSuX~7}h>C*|Ck-w_DZ+}r9!;w z0tJ>3`n)$0U~w zk|cOAcN%zmY~kb!sG^Uonnrfe=}*_BfZKwxe3)OJ^(b${oYxA z7VSk~ayQe`Gl~%3clS+`6c9Jt@aOyqv%6*Q=v9R1y<`8S>ax2K2(3YL07@$I4j2K% zX0sW_jfJq396ryRdZECB7F!`R7OJ&j_vK!?A%Vs7sM3IhlE=Hr28ADr@ofi0UmZ0$Po<;@0Gu+93@9=n6U}Cze_R-;N}+QA3hbp*^wI9 z9JlOdemjkI>-AK#q*!@5&c(OMr9N10w6q(|Tyh=5jPb_9tLu1nzT0BzH1~$R5MS7a zhM2txJ+GX*gh@!u^+X{hIp`v7^VIRsoi27(7qFt?!;p#0JD~L~mp* zF7|0={Z%hX$Gu6L6H=SGFxQcTA%y=Sc2wcmRE75YiMHkjz@aO!RMAG5BAW*@o>-`N##YzT9(=Pu=VK*+Fl>wa*~0MO~Vnh zZ#`43z^Z&WU$xEmfo;k?W$x&EvLQ&AjLj&Y%Uvfa0s4N0gc()kOGu(0C-@Dg{F|f^ zz#=z}zc+^U#oOZk42ySf`GUC+=gy=*w!mDbR-r_3Ni|z4c|mOFx#^M`%}>a1#c7G2bTdDYoO>h_*wYK9AR z*5B#I*;wk#x0wbeqFV=*F5h-SPqO*`OCK4pp+jn=Ndm3wJ7IYQahnu}k@?;9_kP=I zCb3Fa;)>H{*8~&%&yi5oVodON1@Zdc{$GvIpU(;mXo8!W53P-JuRc?5RmxN0ov*c` z^?HccL-I+c&s_hnZv0!)|7Ozvz;rQOB+`yNJ+2O(`Rknho0E%Gv<(rzKM9HcVN9y6 z9zMaYJ7pcm1}n0DFup>aQHMZJ9sv3nz!T*(rN(tt=Nd+!A*u_uUt)lV$~1S6GAkhP z@11Vkk7is#X!;pPW*3#gJZ^vt@}0=cA__f;wbCj57=h9; z<}Hoz{PfwtI7Y;=BsBC33| zwG~)KY6v;MmtVH%$Y}dS`kUg@LwPXgv z49ON!wlT(*iJ3voXPPndt>5=~&iUQvT<1R5b=`m5=f2%QLPEQgL4UWz&Xbts%wCI&LHd zqOOdyXy4+;^?bVQX&kw6qShSx?MjwD)`OAY$GkvM1u(k;9wzv zXSXe>G(3VJ|_@P)RLGMb)cK>ol^Sfib zis`+m1^o?srDG{Nu{J902|kNzZ%dg+FevRSzM1?x$Z@^WU9TEm>0o2~x++SFR76Pk z8kwvBsSDkVC2Iu&1HGH z-bL-6Ol{1{T2kG#(HuwM7+LQ68jvnWT9KXCl-SzVg|C(5!+Tic16fwmmjoNFDnkS( zF<(I8pa02^a&QMf7yvw8w}r+)%6D%Zrpo5;97Gzwths@h4Hb#qdj%-J*<$h;M3|t; zdijr_?9GK*I$QN93ACK6h*Jb8&!az%hjf7ko%E=O0bqS>d~2@oK3QUFVlwlE&(|G% zM0GF1NBFA+hwo|b1NpPNhpQDcVJ@5u#`s`aFpAm${1h$@RCH}9&o14DxiZLl)xnHV z)ZeAihUT$}^ga1DL>TOIr(D10o#Vt@Hzw5 zCjdMWJ6;w)Zj_>QYf?I_lV*TE8vLC?^H!S*w<|mSqQ2VDi$ktUWL#)4`|H^O3!LOU zt9pjmnLBV|jZ+mNVYDwfP-4t6WoEIwLQ4d-2ZCampEkMc_$dU2d^OUj@P0Rwgwyek zd+;QkYf_{OR=qQeRCbp+kNiR+i8lxT#RD8Tjl+g(XTY(8{+O+F+N1&ahUmhG$bva{ z(3|KAKLt>!a9^`I-Hra%yz+Ptye|9_6hDb%y@HZmmd{aGj75(QR*w%<4n^d>?A0lK z8O+V0hosyfPaJ#L470)-9SCxN_%n12W{G`we5DuNFN1qXo2G9<;r;m;@|CR+Zk+VpM0pD%{~lvrO% z_}@40B)=W4WuP&L@U^Jm=URdHuii#W?!haBUNo%Jbq(aUUoyfd-t$6&YD{JW&(GU8 zreq?ff1E&-4jk{j0qiZm^wPEwIs6OzHvIFm#ihNC_I<8dpDU-|>MqJ)oed+WXSESR zI4c9t_0WyCmd;Z~{X@6NrSia{Jn+MbSl8vvUrsrt8}N&zwS&8u3W?8F&4m26O!Lkz z(4qcnBL0JP#Bc5G0Qwmchr0xU-MJWU$@^{ba@;=^Hk#jP{4V)cp>EeH&@m&CEE zH@fUv&0R_UmTC*6`=&LplZ&Lo*sBiJ2l}g4bvj<49Ug`Xc%f9W7SP(s@^B@PIU#XW4+n-S<8hqsc%2(F! zSa3&*oEwPqA~PA`Vko`+gEFo1Kxffs$WywO7~*(kWMzEXxX}V9@RxeT7{zr&kvskS zLdVzDJi$Y^-EV_?aoIVj9-GM~1uHBXcuzab`)FFz*J6@mS`#>_rXdxSL+)*T{>EBl z9W&atT2JKkkOLfOU(T)XLL80OuY823>)a#RN68edVibKb>aOyzeX`19?|7y$PHK?g zMbjGN%16RY8%55_V;^q2)9wHC|M3K0?hlCj&EmMMil_V}lO*N@0#K)(fK%nN_)+je z)iBpFemlO;Zg6YEyO7qxf>K&a-taz6DR;IB^be()-WF?l4bm^n_>CyY&88h757L)C zC}*oatBTCQcGR!ERyt`Ti!0R!FT?OIwnjL9P=vsbbzfC{3Ph4SqE9&R4qP?}_=2A7 zs-xi9MBpKRTN+T7!3IMcZ?jBaW{{OvETwEUb3=~Qdd4{s6Trr-tDWL33w+ z2gQc?Vj_w0=+j6SO#&N_oJh&%68}I64BX?xH<+z5JTlmu6kkA_B_dW7&k>#z-MunnysnA=(t2s zsOEl-O?M6xs%cnGdB(86wJ4ymrKmInUkRN%)w)xZDR&3AUOjx7;gP=UCS2{Kt;MVR z&|h0o)c)l?fY=CYrxAIx<@K|t-!}9B<`k4da0=A&##R0N;RZrs)Dze|FnO5`v;P0W z`A28}>gZ1jv^ZXnqSZc~%6s#Xo2Y)hobcUoWLhyg9SsCNKQ)e8hYU_;e4Hy-VDE@f zr+B*USo#QWIAhkJcP$(C#8jm3N4{^{9UvQVY}B{pa>s@;Gs|Ah{z+dy0h0b@Q!Z28 zoQgj^mG@ktHaOoJGdkKA!G!)=E57Cs$}%%JUEompxQxBAMXY+YaiduR<#Zi0Y`37F z)?;t{h|UQVKVxKAbTPrCJpUnNWvDu@_O45#C=69Qbffa&(!3GAf3PF9^L=8vJK!{T zUbm9*+;-3QU%|}b5x1p%!;ca!sWfVwh7`IL0pLc!>aHINf zU56y#7me{lsfBv|C#d%5EfSd$)dj}Q)9MC+Q-o?D-mVvQZzBu1Azt5bGZy7KLl>%v zEfCskGEDUVv-M)zO|V@jjI5T!CchuxRmVrA#unURIjOOWvd002o|QKCd{>V?((HaO z{OgfKo%h+yRQF_Y_|JG`i6N-L(wh-?{&pHkD`)*6y!OQWI4He+MiWzXXAhO69Q-Jy zZu+_`w(Me&W3iWV%Xqwp{+-Zw5*^2Q^bW`8iQwy0_kkXMC=&pZW&Z;|90`JZgJ&AP z-i-hFPRwrQY!8qPAJY&6u5$ChfvuoOk({#1S+Qrtt0~0na(K7gp-fm@B~l7|aI2;^ zo(dcD_2D!rQH4pM(K0*q?oYxConH>shq)ceI(rMl*Mo3~n`vK4>DG*ahT7e7xL)%b z{hsJplcTCY5xIAOVsLGB_83;0y+#$a-PWA_x$`g^D38wgz9uxYiBQA7*?$+Gtc!hY z?D3}hyVG)c7Z^tFis2QTqmIH+EOg{(Te2?iE@;;jUx0taW02WBjb&BV&FCOKyox0%^+UVXyuil`?B)681$I2QEQTk^`#nKDx%tNU zRQ$;yerWp{3J`z2*l2Ao6JHQk07Uw7wJ64jWw!Jm{QGAzJYFW$Md$}&zMSn&N8MR% z#boVt+K_M9 zFA7R6*JQf+i}(1=Ab$6xi(Q-!7>kotYY};r4vC7AMP6e5cxCw&0GApE1~7on=Im7; zE6!>|OvKU9@EZnlc**erZOnDDoFrMeZp5dVNqzlVb%_XO2|x)my(qm~w%>{^--2T~ zRu9$;k+DV3X1kveFSjr2DB|7XR$b@loJ>@`E_}b%ZyGt94QRW%avc86|3@d_V}n3( zfc4cc|9Osra3P_HNz>|#-zaD(U|an7Q|JIQhd_4QacqjQ0CvL5DbHOy6u}ad^5$hIy^k~y z`y3#JQo<mhDuO@XQx~*3c<~5Tb0&*PI|WzrT3>ITTLp8qxEcF| zzJXp7K~&frN)J1!q_o?la%wkXh85tY1vf*02=Lkvn`t&`=GZlX39U4 zY{46>-cQ~-4*x?Dm+2osg>W)>B77mHZ91|5@ANO8{I;{Qn_TnG@Kaov%hmzwGYRK} R1b#1D%iZTKYR!BS{|h@BQN{oO delta 3916 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 diff --git a/docs/graphics/options_gameinfo_emulation.png b/docs/graphics/options_gameinfo_emulation.png index 0db133505a7fcf9f69c2b8867945958514ff9747..221a08fa5b818b9a3e6556753530d25c9dc42de1 100644 GIT binary patch delta 3357 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 Kq4>Pl!~X(1l;5rZ delta 3292 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 From 6999f69aa2175d0292f05810bc884967810f6b21 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 20 Jun 2020 12:33:07 -0230 Subject: [PATCH 096/104] Last minute update to docs before the 6.2.1 release. --- docs/index.html | 12 +++++++++++- src/common/Version.hxx | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index 5b711a86d..4683365a3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4290,7 +4290,17 @@ Ms Pac-Man (Stella extended codes):
Cartridge.Type:Cart.Type: Indicates the bank-switching type for the game. The value of this property must be either Auto or one of the following (for more information about bank-switching see Kevin Horton's 2600 bankswitching @@ -4058,7 +4058,7 @@ Ms Pac-Man (Stella extended codes):
Cartridge.StartBank:Cart.StartBank: Indicates which bank to use for reading the reset vector.
Cartridge.Sound:Cart.Sound: Indicates if the game should use 1 or 2 channels for sound output. All original Atari 2600 machines supported 1 channel only, but some homebrew games have been written to take advantage of stereo @@ -4119,19 +4119,19 @@ Ms Pac-Man (Stella extended codes): - + - + - + @@ -4232,14 +4232,14 @@ Ms Pac-Man (Stella extended codes):

Console.TelevisionType:Console.TVType: Indicates the default television setting for the game. The value must be Color or BW.
Console.LeftDifficulty:Console.LeftDiff: Indicates the default difficulty setting for the left player. The value must be A or B.
Console.RightDifficulty:Console.RightDiff: Indicates the default difficulty setting for the right player. The value must be A or B.
- + - + - + - + - + - + diff --git a/src/tools/PropSet.pm b/src/tools/PropSet.pm index 7cba557f9..0c40d7452 100755 --- a/src/tools/PropSet.pm +++ b/src/tools/PropSet.pm @@ -3,29 +3,29 @@ package PropSet; # NOTE: If the property types ever change in Stella, the following hashmap # and array must be updated (and stay in sequence) my %prop_type = ( - "Cart.MD5" => 0, - "Cart.Manufacturer" => 1, - "Cart.ModelNo" => 2, - "Cart.Name" => 3, - "Cart.Note" => 4, - "Cart.Rarity" => 5, - "Cart.Sound" => 6, - "Cart.StartBank" => 7, - "Cart.Type" => 8, - "Console.LeftDiff" => 9, - "Console.RightDiff" => 10, - "Console.TVType" => 11, - "Console.SwapPorts" => 12, - "Controller.Left" => 13, - "Controller.Right" => 14, - "Controller.SwapPaddles" => 15, + "Cart.MD5" => 0, + "Cart.Manufacturer" => 1, + "Cart.ModelNo" => 2, + "Cart.Name" => 3, + "Cart.Note" => 4, + "Cart.Rarity" => 5, + "Cart.Sound" => 6, + "Cart.StartBank" => 7, + "Cart.Type" => 8, + "Console.LeftDiff" => 9, + "Console.RightDiff" => 10, + "Console.TVType" => 11, + "Console.SwapPorts" => 12, + "Controller.Left" => 13, + "Controller.Right" => 14, + "Controller.SwapPaddles" => 15, "Controller.PaddlesXCenter" => 16, - "Controller.PaddlesYCenter" => 17, - "Controller.MouseAxis" => 18, - "Display.Format" => 19, - "Display.VCenter" => 20, - "Display.Phosphor" => 21, - "Display.PPBlend" => 22 + "Controller.PaddlesYCenter" => 17, + "Controller.MouseAxis" => 18, + "Display.Format" => 19, + "Display.VCenter" => 20, + "Display.Phosphor" => 21, + "Display.PPBlend" => 22 ); my @prop_type_as_string = ( "Cart.MD5", From 53cd413221a3b9e105a9ad4e942357d46019e2e1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 8 Jun 2020 15:34:10 +0200 Subject: [PATCH 063/104] allow changing TV hue in 1% steps update palette display when defaulting --- src/gui/VideoAudioDialog.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index c51685fcf..7fcc65cf8 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -233,6 +233,7 @@ void VideoAudioDialog::addPaletteTab() CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", kPaletteUpdated) + myTVHue->setStepValue(1); // The resulting palette xpos = myPhaseShiftNtsc->getRight() + fontWidth * 2; @@ -729,6 +730,7 @@ void VideoAudioDialog::setDefaults() myTVBright->setValue(50); myTVGamma->setValue(50); handlePaletteChange(); + handlePaletteUpdate(); break; case 2: // TV effects From e0403d93a3ecf18b60d4ab919c5e9b3d7402daa4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 9 Jun 2020 08:27:14 +0200 Subject: [PATCH 064/104] fixed palette/tv-effects slider rounding issue --- src/common/PaletteHandler.hxx | 2 +- src/common/tv_filters/NTSCFilter.cxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index 3de835d7d..ed46da516 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -126,7 +126,7 @@ class PaletteHandler Convert adjustables from/to 100% scale */ static constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; } - static constexpr uInt32 scaleTo100(float x) { return uInt32(50 * (x + 1.F)); } + static constexpr uInt32 scaleTo100(float x) { return uInt32(50.0001F * (x + 1.F)); } /** Convert palette settings name to enumeration. diff --git a/src/common/tv_filters/NTSCFilter.cxx b/src/common/tv_filters/NTSCFilter.cxx index 9764f1ac3..8e7e899c9 100644 --- a/src/common/tv_filters/NTSCFilter.cxx +++ b/src/common/tv_filters/NTSCFilter.cxx @@ -20,8 +20,8 @@ #include "NTSCFilter.hxx" -constexpr float scaleFrom100(float x) { return (x/50.F) - 1.F; } -constexpr uInt32 scaleTo100(float x) { return uInt32(50*(x+1.F)); } +constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; } +constexpr uInt32 scaleTo100(float x) { return uInt32(50.0001F * (x + 1.F)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string NTSCFilter::setPreset(Preset preset) From 1223e160b9d1edc179474f22d3055a89422fd39d Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jun 2020 11:19:49 -0230 Subject: [PATCH 065/104] Make sure to use correct 'virtual' size of ROM when creating the internal buffer. --- src/emucore/CartEnhanced.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 5295364f1..c462cbcc8 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -52,7 +52,8 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, } } else - mySize = size; + // Make sure to use size defined by the bankswitching scheme + mySize = std::max(size, bsSize); // Initialize ROM with all 0's, to fill areas that the ROM may not cover size_t bufSize = std::max(mySize, System::PAGE_SIZE); @@ -73,7 +74,9 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, // TODO: should we mirror here too?? // Directly copy the ROM image into the buffer - std::copy_n(image.get(), mySize, myImage.get()); + // Only copy up to the amount of data the ROM provides; extra unused + // space will be filled with 0's from above + std::copy_n(image.get(), std::min(mySize, size), myImage.get()); } else { From fb3438aac705534ddfb64e6adbf056511530301f Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jun 2020 12:32:14 -0230 Subject: [PATCH 066/104] Make sure 3E+ ROMs are always internally sized as a multiple 1024 bytes. --- src/common/bspf.hxx | 6 ++++++ src/emucore/Cart3E.cxx | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 24fe8d0a7..a887bf80a 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -140,6 +140,12 @@ namespace BSPF return power2; } + // Get next multiple of the given value + // Note that this only works when multiple is a power of two + inline size_t nextMultipleOf(size_t size, size_t multiple) { + return (size + multiple - 1) & ~(multiple - 1); + } + // Make 2D-arrays using std::array less verbose template using array2D = std::array, ROW>; diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index 263c8b2e9..b03175477 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) + : CartridgeEnhanced(image, size, BSPF::nextMultipleOf(size, 1_KB), md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; From 4f581d67ac905b5c26e3ed167a385a645a4bd91a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jun 2020 15:56:31 -0230 Subject: [PATCH 067/104] Fixed interaction with ideal ROM size between 3E and 3E+. --- src/emucore/Cart3E.cxx | 9 ++++++++- src/emucore/Cart3E.hxx | 17 ++++++++++++++++- src/emucore/Cart3EPlus.cxx | 2 +- src/emucore/CartEnhanced.hxx | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index b03175477..a79e79167 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -22,7 +22,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextMultipleOf(size, 1_KB), md5, settings) + : Cartridge3E(image, size, BSPF::nextMultipleOf(size, 2_KB), md5, settings) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, size_t bsSize, + const string& md5, const Settings& settings) + : CartridgeEnhanced(image, size, bsSize, md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index f2ead51f5..96fc7b28b 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -65,7 +65,7 @@ class Cartridge3E : public CartridgeEnhanced public: /** - Create a new cartridge using the specified image and size + Create a new cartridge using the specified image and size. @param image Pointer to the ROM image @param size The size of the ROM image @@ -76,6 +76,21 @@ class Cartridge3E : public CartridgeEnhanced const Settings& settings); virtual ~Cartridge3E() = default; + protected: + /** + Create a new cartridge using the specified image and size. + This is an alternate version of the constructor, meant to be used + only by classes inheriting from this class. + + @param image Pointer to the ROM image + @param size The size of the ROM image + @param bsSize The size specified by the bankswitching scheme + @param md5 The md5sum of the ROM image + @param settings A reference to the various settings (read-only) + */ + Cartridge3E(const ByteBuffer& image, size_t size, size_t bsSize, + const string& md5, const Settings& settings); + public: /** diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 6c9fe7c2a..6d5ce7d4c 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -22,7 +22,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge3E(image, size, md5, settings) + : Cartridge3E(image, size, BSPF::nextMultipleOf(size, 1_KB), md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index be0ac95de..cd398be11 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -41,8 +41,8 @@ class CartridgeEnhanced : public Cartridge @param image Pointer to the ROM image @param size The size of the ROM image - @param md5 The md5sum of the ROM image @param bsSize The size specified by the bankswitching scheme + @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) */ CartridgeEnhanced(const ByteBuffer& image, size_t size, size_t bsSize, From 754cb5d4c669d53421f3b45c2a56f2c19d7eaa21 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 9 Jun 2020 20:43:37 +0200 Subject: [PATCH 068/104] Revert "take care of odd ROM sizes (fixes #653)" This reverts commit bc8211b4436b03ab264f20ab4185c16a30a0ed18. --- src/emucore/CartEnhanced.cxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index c462cbcc8..00c7334ed 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -348,7 +348,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myCurrentSegOffset[std::min((address & ROM_MASK) >> myBankShift, romBankCount() - 1)] >> myBankShift; + return myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -360,8 +360,7 @@ uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::romBankCount() const { - // take care of too small ROMs - return uInt16((mySize + ((1 << myBankShift) - 1)) >> myBankShift); + return uInt16(mySize >> myBankShift); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 46e7830c2b940be57d2842d6361a433975db47fb Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jun 2020 16:45:53 -0230 Subject: [PATCH 069/104] Remove focus from description in debugger CartRAM widget. --- src/debugger/gui/CartRamWidget.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/debugger/gui/CartRamWidget.cxx b/src/debugger/gui/CartRamWidget.cxx index 84cc8b9ab..76c8e972a 100644 --- a/src/debugger/gui/CartRamWidget.cxx +++ b/src/debugger/gui/CartRamWidget.cxx @@ -74,7 +74,6 @@ CartRamWidget::CartRamWidget( myDesc->setEditable(false); myDesc->setEnabled(false); myDesc->setList(sl); - addFocusWidget(myDesc); ypos += myDesc->getHeight() + myFontHeight / 2; From f68e10a1560d7664e781ddf6c59ba33ff36b469e Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jun 2020 19:00:35 -0230 Subject: [PATCH 070/104] Updated changelog and minimum compiler requirements in the docs. --- Changes.txt | 11 +++++++++++ docs/index.html | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Changes.txt b/Changes.txt index aeb71411b..27eb65a84 100644 --- a/Changes.txt +++ b/Changes.txt @@ -19,6 +19,17 @@ apply the properties to the ROM. [NOTE: this was present in 6.2, but was mistakenly left out of the changelog] + * Make NTSC custom phase shift not affect Yellow anymore. + + * Allow changing palette adjustables in 1% steps again. + + * Fixed some bugs in 3E+ scheme when using non-standard ROM sizes. + + * Updated documentation for changes in ROM properties key names. + + * The codebase now compiles under gcc6 again. Future versions will + require gcc7, though. + -Have fun! diff --git a/docs/index.html b/docs/index.html index 69e1aff77..41be21bac 100644 --- a/docs/index.html +++ b/docs/index.html @@ -355,12 +355,11 @@

The Linux version of Stella is designed to work on a Linux Workstation with the following:

    -
  • Linux Kernel 3.x
  • i386 or x86_64 class machine, with 32 or 64-bit distribution
  • OpenGL capable video card
  • Other architectures (MIPS, PPC, PPC64, etc.) have been confirmed to work, but aren't as well tested as i386/x86_64
  • -
  • GNU g++ v/5 or Clang v/3.5 (with C++14 support) and the make utility are required for compiling the Stella source code
  • +
  • GNU g++ v/6 or Clang v/3.9 (with C++14 support) and the make utility are required for compiling the Stella source code

From 2783c1cabe9f7287fc3807e9d78d2505b48d8209 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 10 Jun 2020 11:39:55 -0230 Subject: [PATCH 071/104] Make first 3 segments of 3E+ point to random banks, according to the documentation (fixes #660). --- src/debugger/gui/Cart3EPlusWidget.cxx | 2 +- src/emucore/Cart3EPlus.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debugger/gui/Cart3EPlusWidget.cxx b/src/debugger/gui/Cart3EPlusWidget.cxx index a0d97ad2b..163dc23fd 100644 --- a/src/debugger/gui/Cart3EPlusWidget.cxx +++ b/src/debugger/gui/Cart3EPlusWidget.cxx @@ -46,7 +46,7 @@ string Cartridge3EPlusWidget::description() "RAM bank & segment selected by writing to $3E\n" " Lower 512b of segment for read access\n" " Upper 512b of segment for write access\n" - "Startup bank = 0/-1/-1/0 (ROM)\n"; + "Startup bank = -1/-1/-1/0 (ROM)\n"; // Eventually, we should query this from the debugger/disassembler uInt16 start = (image[0x400 - 3] << 8) | image[0x400 - 4]; diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 6d5ce7d4c..818d48c1f 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -34,7 +34,7 @@ void Cartridge3EPlus::reset() { CartridgeEnhanced::reset(); - // 1st segment in mapped to start bank in CartridgeEnhanced + bank(mySystem->randGenerator().next() % romBankCount(), 0); bank(mySystem->randGenerator().next() % romBankCount(), 1); bank(mySystem->randGenerator().next() % romBankCount(), 2); bank(startBank(), 3); From e8fd51453c6755c006f408f1e2f3c8786726561b Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 10 Jun 2020 16:59:27 -0230 Subject: [PATCH 072/104] Fix Pitfall II not working (fixes #661). Note that I've refactored all the constructors to prevent this issue from happening again. It already happened with 3E+/3E, and now DPC/F8. Also, FA2/FA looked suspicious. --- Changes.txt | 2 ++ src/emucore/Cart0840.cxx | 5 +++-- src/emucore/Cart0840.hxx | 3 ++- src/emucore/Cart2K.cxx | 5 +++-- src/emucore/Cart2K.hxx | 3 ++- src/emucore/Cart3E.cxx | 13 ++++--------- src/emucore/Cart3E.hxx | 19 +++---------------- src/emucore/Cart3EPlus.cxx | 6 ++++-- src/emucore/Cart3EPlus.hxx | 4 +++- src/emucore/Cart3F.cxx | 6 ++++-- src/emucore/Cart3F.hxx | 4 +++- src/emucore/Cart4K.cxx | 5 +++-- src/emucore/Cart4K.hxx | 3 ++- src/emucore/Cart4KSC.cxx | 5 +++-- src/emucore/Cart4KSC.hxx | 3 ++- src/emucore/CartBF.cxx | 5 +++-- src/emucore/CartBF.hxx | 3 ++- src/emucore/CartBFSC.cxx | 5 +++-- src/emucore/CartBFSC.hxx | 3 ++- src/emucore/CartCV.cxx | 5 +++-- src/emucore/CartCV.hxx | 3 ++- src/emucore/CartDF.cxx | 5 +++-- src/emucore/CartDF.hxx | 3 ++- src/emucore/CartDFSC.cxx | 5 +++-- src/emucore/CartDFSC.hxx | 3 ++- src/emucore/CartDPC.cxx | 5 +++-- src/emucore/CartDPC.hxx | 3 ++- src/emucore/CartE0.cxx | 5 +++-- src/emucore/CartE0.hxx | 3 ++- src/emucore/CartEF.cxx | 5 +++-- src/emucore/CartEF.hxx | 3 ++- src/emucore/CartEFSC.cxx | 5 +++-- src/emucore/CartEFSC.hxx | 3 ++- src/emucore/CartEnhanced.cxx | 4 ++-- src/emucore/CartEnhanced.hxx | 7 ++++--- src/emucore/CartF0.cxx | 5 +++-- src/emucore/CartF0.hxx | 3 ++- src/emucore/CartF4.cxx | 5 +++-- src/emucore/CartF4.hxx | 3 ++- src/emucore/CartF4SC.cxx | 7 ++++--- src/emucore/CartF4SC.hxx | 3 ++- src/emucore/CartF6.cxx | 5 +++-- src/emucore/CartF6.hxx | 3 ++- src/emucore/CartF6SC.cxx | 7 ++++--- src/emucore/CartF6SC.hxx | 3 ++- src/emucore/CartF8.cxx | 5 +++-- src/emucore/CartF8.hxx | 3 ++- src/emucore/CartF8SC.cxx | 5 +++-- src/emucore/CartF8SC.hxx | 3 ++- src/emucore/CartFA.cxx | 5 +++-- src/emucore/CartFA.hxx | 3 ++- src/emucore/CartFA2.cxx | 5 +++-- src/emucore/CartFA2.hxx | 3 ++- src/emucore/CartFC.cxx | 6 ++++-- src/emucore/CartFC.hxx | 4 +++- src/emucore/CartFE.cxx | 5 +++-- src/emucore/CartFE.hxx | 3 ++- src/emucore/CartMDM.cxx | 6 ++++-- src/emucore/CartMDM.hxx | 4 +++- src/emucore/CartSB.cxx | 6 ++++-- src/emucore/CartSB.hxx | 4 +++- src/emucore/CartTVBoy.cxx | 5 +++-- src/emucore/CartTVBoy.hxx | 3 ++- src/emucore/CartUA.cxx | 2 +- src/emucore/CartWD.cxx | 5 +++-- src/emucore/CartWD.hxx | 3 ++- src/emucore/CartX07.cxx | 5 +++-- src/emucore/CartX07.hxx | 3 ++- 68 files changed, 183 insertions(+), 126 deletions(-) diff --git a/Changes.txt b/Changes.txt index 27eb65a84..507bfc84f 100644 --- a/Changes.txt +++ b/Changes.txt @@ -14,6 +14,8 @@ 6.2 to 6.2.1: (XXX xx, 2020) + * Fixed Pitfall II ROM not working correctly. + * A ROM properties file may now be placed next to the ROM (with the same name as the ROM, except ending in .pro), and Stella will automatically apply the properties to the ROM. [NOTE: this was present in 6.2, but diff --git a/src/emucore/Cart0840.cxx b/src/emucore/Cart0840.cxx index 894b8eed7..c560b0a1b 100644 --- a/src/emucore/Cart0840.cxx +++ b/src/emucore/Cart0840.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 8_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/Cart0840.hxx b/src/emucore/Cart0840.hxx index af1977485..0d120aad4 100644 --- a/src/emucore/Cart0840.hxx +++ b/src/emucore/Cart0840.hxx @@ -44,9 +44,10 @@ class Cartridge0840 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ Cartridge0840(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~Cartridge0840() = default; public: diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index c70cc373f..ee0974549 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -20,7 +20,8 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 2_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index 0ed6fedef..878df4714 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -47,9 +47,10 @@ class Cartridge2K : public CartridgeEnhanced @param size The size of the ROM image (<= 2048 bytes) @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ Cartridge2K(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 2_KB); virtual ~Cartridge2K() = default; public: diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index a79e79167..e3d049eea 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -21,15 +21,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge3E(image, size, BSPF::nextMultipleOf(size, 2_KB), md5, settings) -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, size_t bsSize, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, bsSize, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, + bsSize == 0 ? BSPF::nextMultipleOf(size, 2_KB) : bsSize) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 96fc7b28b..60e50613a 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -71,26 +71,13 @@ class Cartridge3E : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~Cartridge3E() = default; - protected: - /** - Create a new cartridge using the specified image and size. - This is an alternate version of the constructor, meant to be used - only by classes inheriting from this class. - - @param image Pointer to the ROM image - @param size The size of the ROM image - @param bsSize The size specified by the bankswitching scheme - @param md5 The md5sum of the ROM image - @param settings A reference to the various settings (read-only) - */ - Cartridge3E(const ByteBuffer& image, size_t size, size_t bsSize, - const string& md5, const Settings& settings); - public: /** diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 818d48c1f..2233b0d71 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -21,8 +21,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge3E(image, size, BSPF::nextMultipleOf(size, 1_KB), md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : Cartridge3E(image, size, md5, settings, + bsSize == 0 ? BSPF::nextMultipleOf(size, 1_KB) : bsSize) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index fe6a0a263..9abd5cb09 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -100,9 +100,11 @@ class Cartridge3EPlus: public Cartridge3E @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~Cartridge3EPlus() = default; public: diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 20d9cef1d..a44c28a5e 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -21,8 +21,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3F::Cartridge3F(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, + bsSize == 0 ? BSPF::nextPowerOfTwo(size) : bsSize) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index 7bdcbd99c..f5eeac809 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -50,9 +50,11 @@ class Cartridge3F : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~Cartridge3F() = default; public: diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index 0a3e27bdc..830cffd49 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -20,7 +20,8 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4K::Cartridge4K(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 4_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/Cart4K.hxx b/src/emucore/Cart4K.hxx index 1a7c428f4..cc2bb5aef 100644 --- a/src/emucore/Cart4K.hxx +++ b/src/emucore/Cart4K.hxx @@ -44,9 +44,10 @@ class Cartridge4K : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 4_KB); virtual ~Cartridge4K() = default; public: diff --git a/src/emucore/Cart4KSC.cxx b/src/emucore/Cart4KSC.cxx index 92d2e946e..50ad78e8b 100644 --- a/src/emucore/Cart4KSC.cxx +++ b/src/emucore/Cart4KSC.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4KSC::Cartridge4KSC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge4K(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : Cartridge4K(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/Cart4KSC.hxx b/src/emucore/Cart4KSC.hxx index 3f28de9ce..a2197e018 100644 --- a/src/emucore/Cart4KSC.hxx +++ b/src/emucore/Cart4KSC.hxx @@ -45,9 +45,10 @@ class Cartridge4KSC : public Cartridge4K @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ Cartridge4KSC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 4_KB); virtual ~Cartridge4KSC() = default; public: diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index 065b657dc..cd815c518 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBF::CartridgeBF(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 256_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartBF.hxx b/src/emucore/CartBF.hxx index 23c51f760..5190f73da 100644 --- a/src/emucore/CartBF.hxx +++ b/src/emucore/CartBF.hxx @@ -45,9 +45,10 @@ class CartridgeBF : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeBF(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 256_KB); virtual ~CartridgeBF() = default; public: diff --git a/src/emucore/CartBFSC.cxx b/src/emucore/CartBFSC.cxx index bd9793893..ac8a105b3 100644 --- a/src/emucore/CartBFSC.cxx +++ b/src/emucore/CartBFSC.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBFSC::CartridgeBFSC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeBF(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeBF(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartBFSC.hxx b/src/emucore/CartBFSC.hxx index 9bb22aa0a..4a660ecc8 100644 --- a/src/emucore/CartBFSC.hxx +++ b/src/emucore/CartBFSC.hxx @@ -45,9 +45,10 @@ class CartridgeBFSC : public CartridgeBF @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeBFSC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 256_KB); virtual ~CartridgeBFSC() = default; /** diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index 8e8e6504e..8fe746f1a 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 2_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index a5403b19f..809d9b373 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -47,9 +47,10 @@ class CartridgeCV : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeCV(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 2_KB); virtual ~CartridgeCV() = default; public: diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index f95ebcc93..58206a3b5 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 128_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartDF.hxx b/src/emucore/CartDF.hxx index 3c33e8bff..18d0f2489 100644 --- a/src/emucore/CartDF.hxx +++ b/src/emucore/CartDF.hxx @@ -45,9 +45,10 @@ class CartridgeDF : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeDF(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 128_KB); virtual ~CartridgeDF() = default; public: diff --git a/src/emucore/CartDFSC.cxx b/src/emucore/CartDFSC.cxx index f759136a7..4dafe3bb7 100644 --- a/src/emucore/CartDFSC.cxx +++ b/src/emucore/CartDFSC.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDFSC::CartridgeDFSC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeDF(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeDF(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartDFSC.hxx b/src/emucore/CartDFSC.hxx index 637dde3da..efc6d30e8 100644 --- a/src/emucore/CartDFSC.hxx +++ b/src/emucore/CartDFSC.hxx @@ -45,9 +45,10 @@ class CartridgeDFSC : public CartridgeDF @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeDFSC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 128_KB); virtual ~CartridgeDFSC() = default; public: diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index bc8962b1b..c77aacd8a 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -22,8 +22,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDPC::CartridgeDPC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeF8(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeF8(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index e0a1b866e..4d90fb140 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -46,9 +46,10 @@ class CartridgeDPC : public CartridgeF8 @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeDPC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 10_KB); virtual ~CartridgeDPC() = default; public: diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index 7a10c3e34..9204d5619 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE0::CartridgeE0(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 8_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { myBankShift = BANK_SHIFT; } diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 84c9ae667..70af8f85d 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -53,9 +53,10 @@ class CartridgeE0 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeE0(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~CartridgeE0() = default; public: diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 175b42263..c063b0c05 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 64_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartEF.hxx b/src/emucore/CartEF.hxx index ff71b9909..2c86d0d71 100644 --- a/src/emucore/CartEF.hxx +++ b/src/emucore/CartEF.hxx @@ -45,9 +45,10 @@ class CartridgeEF : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeEF(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 64_KB); virtual ~CartridgeEF() = default; public: diff --git a/src/emucore/CartEFSC.cxx b/src/emucore/CartEFSC.cxx index c70cff194..f73557245 100644 --- a/src/emucore/CartEFSC.cxx +++ b/src/emucore/CartEFSC.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEFSC::CartridgeEFSC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEF(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEF(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartEFSC.hxx b/src/emucore/CartEFSC.hxx index f6c7e40ea..ac95c9e2c 100644 --- a/src/emucore/CartEFSC.hxx +++ b/src/emucore/CartEFSC.hxx @@ -46,9 +46,10 @@ class CartridgeEFSC : public CartridgeEF @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeEFSC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 64_KB); virtual ~CartridgeEFSC() = default; public: diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 00c7334ed..574dacca8 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -21,8 +21,8 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, - size_t bsSize, const string& md5, - const Settings& settings) + const string& md5, const Settings& settings, + size_t bsSize) : Cartridge(settings, md5) { // ROMs are not always at the 'legal' size for their associated diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index cd398be11..e15fb8ba1 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -41,12 +41,13 @@ class CartridgeEnhanced : public Cartridge @param image Pointer to the ROM image @param size The size of the ROM image - @param bsSize The size specified by the bankswitching scheme @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ - CartridgeEnhanced(const ByteBuffer& image, size_t size, size_t bsSize, - const string& md5, const Settings& settings); + CartridgeEnhanced(const ByteBuffer& image, size_t size, + const string& md5, const Settings& settings, + size_t bsSize); virtual ~CartridgeEnhanced() = default; public: diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index f21bba07e..0429109e3 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -19,8 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF0::CartridgeF0(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 64_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index 0d5837066..e49b8ce31 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -42,9 +42,10 @@ class CartridgeF0 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF0(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 64_KB); virtual ~CartridgeF0() = default; public: diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index 609fd0b03..c00163efb 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -19,8 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4::CartridgeF4(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 32_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index d44e96640..81a5e176e 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -41,9 +41,10 @@ class CartridgeF4 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF4(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 32_KB); virtual ~CartridgeF4() = default; public: diff --git a/src/emucore/CartF4SC.cxx b/src/emucore/CartF4SC.cxx index 4fe6e13eb..d012874c6 100644 --- a/src/emucore/CartF4SC.cxx +++ b/src/emucore/CartF4SC.cxx @@ -19,9 +19,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4SC::CartridgeF4SC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeF4(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeF4(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; - myRamMask = RAM_SIZE - 1; + myRamMask = RAM_SIZE - 1; } diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index 58b255e42..49f1278ac 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -42,9 +42,10 @@ class CartridgeF4SC : public CartridgeF4 @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF4SC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 32_KB); virtual ~CartridgeF4SC() = default; public: diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 572909952..0e4bcf678 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -19,8 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6::CartridgeF6(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 16_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 16faeebab..7707f1ef6 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -41,9 +41,10 @@ class CartridgeF6 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF6(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 16_KB); virtual ~CartridgeF6() = default; public: diff --git a/src/emucore/CartF6SC.cxx b/src/emucore/CartF6SC.cxx index 15613a357..084091d12 100644 --- a/src/emucore/CartF6SC.cxx +++ b/src/emucore/CartF6SC.cxx @@ -19,9 +19,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6SC::CartridgeF6SC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeF6(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeF6(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; - myRamMask = RAM_SIZE - 1; + myRamMask = RAM_SIZE - 1; } diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index c61c9715f..4365036bb 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -42,9 +42,10 @@ class CartridgeF6SC : public CartridgeF6 @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF6SC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 16_KB); virtual ~CartridgeF6SC() = default; public: diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index 7ea1216a5..732cb306d 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -19,8 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8::CartridgeF8(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 8_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index 29b308808..90b34497a 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -41,9 +41,10 @@ class CartridgeF8 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF8(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~CartridgeF8() = default; public: diff --git a/src/emucore/CartF8SC.cxx b/src/emucore/CartF8SC.cxx index 98ce4357f..9607d9687 100644 --- a/src/emucore/CartF8SC.cxx +++ b/src/emucore/CartF8SC.cxx @@ -19,8 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8SC::CartridgeF8SC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeF8(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeF8(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index c5a005543..3eb3539ae 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -42,9 +42,10 @@ class CartridgeF8SC : public CartridgeF8 @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeF8SC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~CartridgeF8SC() = default; public: diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index bc82dec84..ec242f615 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 12_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index a2f197b75..d234de743 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -45,9 +45,10 @@ class CartridgeFA : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 12_KB); virtual ~CartridgeFA() = default; public: diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 14c8f2156..2443b106a 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeFA(image, size, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeFA(image, size, md5, settings, bsSize) { // 29/32K version of FA2 has valid data @ 1K - 29K const uInt8* img_ptr = image.get(); diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index 16d33bf2b..ea60fbe45 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -57,9 +57,10 @@ class CartridgeFA2 : public CartridgeFA @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the settings object + @param bsSize The size specified by the bankswitching scheme */ CartridgeFA2(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 28_KB); virtual ~CartridgeFA2() = default; public: diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index 9b945c666..1b431592e 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -20,8 +20,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFC::CartridgeFC(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, + bsSize == 0 ? BSPF::nextPowerOfTwo(size) : bsSize) { } diff --git a/src/emucore/CartFC.hxx b/src/emucore/CartFC.hxx index 5858ae85a..92be2a421 100644 --- a/src/emucore/CartFC.hxx +++ b/src/emucore/CartFC.hxx @@ -47,9 +47,11 @@ class CartridgeFC : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ CartridgeFC(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~CartridgeFC() = default; public: diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index a9602e88a..d0c01886b 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -21,8 +21,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFE::CartridgeFE(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 8_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { myDirectPeek = false; } diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index 6c453d284..77ebee767 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -87,9 +87,10 @@ class CartridgeFE : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeFE(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~CartridgeFE() = default; public: diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index 022bc1bdb..f92563ec2 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -20,8 +20,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeMDM::CartridgeMDM(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, + bsSize == 0 ? BSPF::nextPowerOfTwo(size) : bsSize) { } diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index fe17ae628..4e12571e1 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -56,9 +56,11 @@ class CartridgeMDM : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ CartridgeMDM(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~CartridgeMDM() = default; public: diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 8ad55f28d..18d160cff 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -20,8 +20,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeSB::CartridgeSB(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, BSPF::nextPowerOfTwo(size), md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, + bsSize == 0 ? BSPF::nextPowerOfTwo(size) : bsSize) { } diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index 85c8e9ccb..17cea387c 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -45,9 +45,11 @@ class CartridgeSB : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ CartridgeSB(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~CartridgeSB() = default; public: diff --git a/src/emucore/CartTVBoy.cxx b/src/emucore/CartTVBoy.cxx index 0626da0aa..50d66cb57 100644 --- a/src/emucore/CartTVBoy.cxx +++ b/src/emucore/CartTVBoy.cxx @@ -20,8 +20,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeTVBoy::CartridgeTVBoy(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 512_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartTVBoy.hxx b/src/emucore/CartTVBoy.hxx index 90072a08d..d1787e55b 100644 --- a/src/emucore/CartTVBoy.hxx +++ b/src/emucore/CartTVBoy.hxx @@ -44,9 +44,10 @@ class CartridgeTVBoy : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeTVBoy(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 512_KB); virtual ~CartridgeTVBoy() = default; public: diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 23caa5091..e73f166db 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -22,7 +22,7 @@ CartridgeUA::CartridgeUA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, bool swapHotspots) - : CartridgeEnhanced(image, size, 8_KB, md5, settings), + : CartridgeEnhanced(image, size, md5, settings, 8_KB), mySwappedHotspots(swapHotspots) { } diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index f9c7463f3..d985abd00 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -22,8 +22,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeWD::CartridgeWD(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 8_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { // Copy the ROM image into my buffer if(size == 8_KB + 3) diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 398571a52..4c1d9d3d9 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -65,9 +65,10 @@ class CartridgeWD : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeWD(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 8_KB); virtual ~CartridgeWD() = default; public: diff --git a/src/emucore/CartX07.cxx b/src/emucore/CartX07.cxx index e28869920..4f3294d5c 100644 --- a/src/emucore/CartX07.cxx +++ b/src/emucore/CartX07.cxx @@ -22,8 +22,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeX07::CartridgeX07(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, 64_KB, md5, settings) + const string& md5, const Settings& settings, + size_t bsSize) + : CartridgeEnhanced(image, size, md5, settings, bsSize) { } diff --git a/src/emucore/CartX07.hxx b/src/emucore/CartX07.hxx index 3cde4efdf..3f59ca7c3 100644 --- a/src/emucore/CartX07.hxx +++ b/src/emucore/CartX07.hxx @@ -54,9 +54,10 @@ class CartridgeX07 : public CartridgeEnhanced @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme */ CartridgeX07(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 64_KB); virtual ~CartridgeX07() = default; public: From 45b11cea538678e153bb737b5b5a2dd7b32e96d2 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 11 Jun 2020 16:20:10 +0200 Subject: [PATCH 073/104] Fixed #662 (3E+ initialization description) --- src/emucore/Cart3EPlus.hxx | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 9abd5cb09..ab8696372 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -42,7 +42,7 @@ class System; ROM: - Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal + Note: In descriptions $F000 is equivalent to $1000 -- that is, we only deal with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000 So, mask with top bits clear :) when reading this document. @@ -51,16 +51,10 @@ class System; The last 1K ROM ($FC00-$FFFF) segment in the 6502 address space (ie: $1C00-$1FFF) is initialised to point to the FIRST 1K of the ROM image, so the reset vectors - must be placed at the end of the first 1K in the ROM image. Note, this is - DIFFERENT to 3E which switches in the UPPER bank and this bank is fixed. This - allows variable sized ROM without having to detect size. First bank (0) in ROM is - the default fixed bank mapped to $FC00. + must be placed at the end of the first 1K in the ROM image. - The system requires the reset vectors to be valid on a reset, so either the - hardware first switches in the first bank, or the programmer must ensure - that the reset vector is present in ALL ROM banks which might be switched - into the last bank area. Currently the latter (programmer onus) is required, - but it would be nice for the cartridge hardware to auto-switch on reset. + Note: This is DIFFERENT to 3E which switches in the UPPER bank and this bank is + fixed. This allows variable sized ROM without having to detect size. ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank # indicates the destination segment (0-3, corresponding to $F000, $F400, $F800, @@ -100,11 +94,9 @@ class Cartridge3EPlus: public Cartridge3E @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) - @param bsSize The size specified by the bankswitching scheme - (where 0 means variable-sized ROM) */ Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings, size_t bsSize = 0); + const Settings& settings); virtual ~Cartridge3EPlus() = default; public: From 041429ccfb690006e655d27956a6a187e8e96b80 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 11 Jun 2020 12:02:50 -0230 Subject: [PATCH 074/104] Fix compile error from last commit. --- src/emucore/Cart3EPlus.hxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index ab8696372..2ba54d313 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -94,9 +94,11 @@ class Cartridge3EPlus: public Cartridge3E @param size The size of the ROM image @param md5 The md5sum of the ROM image @param settings A reference to the various settings (read-only) + @param bsSize The size specified by the bankswitching scheme + (where 0 means variable-sized ROM) */ Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings, size_t bsSize = 0); virtual ~Cartridge3EPlus() = default; public: From 5560fb8976e01bc7c838c5e8904e52e9ffbd24ff Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 11 Jun 2020 12:18:30 -0230 Subject: [PATCH 075/104] Updated docs: modified text for saving "pixel-exact" images, and Cart.VCenter range. --- docs/index.html | 6 +++--- src/gui/SnapshotDialog.cxx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.html b/docs/index.html index 41be21bac..85d019040 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3172,9 +3172,9 @@

- + - +
Cartridge.Name:Cart.Name: Indicates the actual name of the game. When you save snapshots, load/save state files, or use the ROM Audit Mode functionality, this is the name that will be used for the respective file(s).
Cartridge.MD5:Cart.MD5: Indicates the MD5 checksum of the ROM image as a string of hexadecimal digits. Stella uses this property while attempting to match a game with its block of properties. If the @@ -4250,22 +4250,22 @@ Ms Pac-Man (Stella extended codes):
Cartridge.Manufacturer:Cart.Manufacturer: Indicates the game's manufacturer.
Cartridge.ModelNo:Cart.ModelNo: Indicates the manufacturer's model number for the game.
Cartridge.Rarity:Cart.Rarity: Indicates how rare a cartridge is, based on the scale described on AtariAge.
Cartridge.Note:Cart.Note: Contains any special notes about playing the game.
Save pathSpecifies where to save snapshots-snapsavedir
Continuous snapshot intervalInterval (in seconds) between snapshots-ssinterval
Use actual ROM nameUse the actual ROM filename instead of the internal database name.-snapname
Use actual ROM nameUse the actual ROM filename instead of the internal database name-snapname
Overwrite existing filesWhether to overwrite old snapshots-sssingle
Ignore scaling (1x mode)Save snapshot in 1x mode without scaling-ss1x
Create pixel-exact image (no zoom/post-processing)Save snapshot using the exact pixels from the TIA image, without zoom or any post-processing effects-ss1x
Display.VCenter: Indicates the offset for the vertical center of the display. - The value must be n such that -5 <= n <= 5. + The value must be n such that -20 <= n <= 20.
_BASEDIR_/stella.pro
-

Stella will require a restart for changes to this file to take effect.

+

The buttons at the bottom of the dialog work as follows: +

    +
  • Defaults: Reset the properties to those built into Stella.
  • +
  • Save: Save the properties for the currently selected ROM only + to a properties file in the users default save directory.
  • +
  • OK: Merge/commit any changes into the ROM properties database, which + contains info on all ROMs.
  • +
  • Cancel: Revert any changes in the dialog, and cancel the operation.
  • +
+

Note that for any changes made here, Stella will require a restart for the + changes to take effect.


Palette Support

diff --git a/src/common/Version.hxx b/src/common/Version.hxx index b0e339035..9c070d208 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.2.1" -#define STELLA_BUILD "6039" +#define STELLA_BUILD "6041" #endif From 538eecc5d6cf703cb157fe38b6a16fbf2f1bff6d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 20 Jun 2020 18:01:12 +0200 Subject: [PATCH 097/104] minor wording fix --- docs/index.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/index.html b/docs/index.html index 4683365a3..276fbae1b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4270,6 +4270,16 @@ Ms Pac-Man (Stella extended codes): +

The buttons at the bottom of the dialogs work as follows: +

    +
  • Defaults: Reset the properties to those built into Stella.
  • +
  • Save: Save the properties for the currently selected ROM only + to a properties file in the users default save directory.
  • +
  • OK: Merge/commit any changes into the ROM properties database, which + contains info on all ROMs.
  • +
  • Cancel: Revert any changes in the dialog, and cancel the operation.
  • +
+

The name of the properties file will depend on the version of Stella, as follows:

@@ -4290,17 +4300,7 @@ Ms Pac-Man (Stella extended codes):
_BASEDIR_/stella.pro
-

The buttons at the bottom of the dialog work as follows: -

    -
  • Defaults: Reset the properties to those built into Stella.
  • -
  • Save: Save the properties for the currently selected ROM only - to a properties file in the users default save directory.
  • -
  • OK: Merge/commit any changes into the ROM properties database, which - contains info on all ROMs.
  • -
  • Cancel: Revert any changes in the dialog, and cancel the operation.
  • -
-

Note that for any changes made here, Stella will require a restart for the - changes to take effect.

+

Note: For manual changes to the property files Stella will require a restart to take effect.


Palette Support

From ad930ef34b6ced126c708e2a105836504c41623f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 21 Jun 2020 15:58:58 +0200 Subject: [PATCH 098/104] Added new interface palette 'Dark' --- Changes.txt | 5 +++++ src/emucore/FrameBuffer.cxx | 14 ++++++++++++++ src/emucore/FrameBuffer.hxx | 3 ++- src/emucore/Settings.cxx | 3 ++- src/gui/UIDialog.cxx | 1 + 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Changes.txt b/Changes.txt index 749085128..65b7dbec1 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,6 +12,11 @@ Release History =========================================================================== +6.2.1 to 6.3 (XXXX XX, 2020) + + * Added new interface palette 'Dark'. (TODO: DOC) + + 6.2 to 6.2.1: (June 20, 2020) * Fixed Pitfall II ROM not working correctly. diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 97af29fcf..f2c3fc8f6 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -862,6 +862,7 @@ void FrameBuffer::setUIPalette() const UIPaletteArray& ui_palette = (myOSystem.settings().getString("uipalette") == "classic") ? ourClassicUIPalette : (myOSystem.settings().getString("uipalette") == "light") ? ourLightUIPalette : + (myOSystem.settings().getString("uipalette") == "dark") ? ourDarkUIPalette : ourStandardUIPalette; for(size_t i = 0, j = myFullPalette.size() - ui_palette.size(); @@ -1553,3 +1554,16 @@ UIPaletteArray FrameBuffer::ourLightUIPalette = { 0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0 // other } }; + +UIPaletteArray FrameBuffer::ourDarkUIPalette = { + { 0x646464, 0xc0c0c0, 0x3c3c3c, 0x282828, 0x989898, // base + 0xc0c0c0, 0x1567a5, 0x0059a3, 0xc0c0c0, // text + 0x202020, 0x000000, 0x0059a3, 0xb0b0b0, // UI elements + 0x282828, 0x00467f, 0x646464, 0x0059a3, 0xc0c0c0, 0xc0c0c0, // buttons + 0x989898, // checkbox + 0x3c3c3c, 0x646464, // scrollbar + 0x7f2020, 0xc0c0c0, 0xe00000, 0xc00000, // debugger + 0x989898, 0x0059a3, 0x3c3c3c, 0x000000, 0x3c3c3c, // slider + 0x000000, 0x989898, 0x202020, 0x646464, 0x3c3c3c // other + } +}; diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 0a55a0f89..544c8c6c1 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -714,7 +714,8 @@ class FrameBuffer FullPaletteArray myFullPalette; // Holds UI palette data (for each variation) - static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette, ourLightUIPalette; + static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette, + ourLightUIPalette, ourDarkUIPalette; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index e6d81abdd..0c5073d45 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -524,7 +524,8 @@ void Settings::usage() const << " launcher\n" << " -romloadcount Number of ROM to load next from multicard\n" << " -uipalette \n" + << " classic|\n" + << " light|dark>\n" << " -hidpi <0|1> Enable HiDPI mode\n" << " -dialogfont Date: Wed, 1 Jul 2020 23:51:49 +0200 Subject: [PATCH 099/104] allow breakpoints in data areas (fixes #668) --- src/debugger/gui/RomWidget.cxx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 010ae5f0b..52b2e81b8 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -165,13 +165,16 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomWidget::toggleBreak(int disasm_line) { + Debugger& debugger = instance().debugger(); const CartDebug::DisassemblyList& list = - instance().debugger().cartDebug().disassembly().list; + debugger.cartDebug().disassembly().list; + if(disasm_line >= int(list.size())) return; - if(list[disasm_line].address != 0 && list[disasm_line].bytes != "") - instance().debugger().toggleBreakPoint(list[disasm_line].address, - instance().debugger().cartDebug().getBank(list[disasm_line].address)); + const uInt16 address = list[disasm_line].address; + + if(address != 0) + debugger.toggleBreakPoint(address, debugger.cartDebug().getBank(address)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 33e57a83caa991e20b522eabf7448fa230312227 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 2 Jul 2020 09:33:16 +0200 Subject: [PATCH 100/104] suppress fullscreen mode switches in Time Machine mode (fixes #670) --- src/emucore/FrameBuffer.cxx | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index f2c3fc8f6..6ae234fa0 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -992,21 +992,33 @@ void FrameBuffer::setFullscreen(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::toggleFullscreen(bool toggle) { - const bool isFullscreen = toggle ? !fullScreen() : fullScreen(); - - setFullscreen(isFullscreen); - - if(myBufferType == BufferType::Emulator) + switch (myOSystem.eventHandler().state()) { - ostringstream msg; + case EventHandlerState::LAUNCHER: + case EventHandlerState::EMULATION: + case EventHandlerState::PAUSE: + case EventHandlerState::DEBUGGER: + { + const bool isFullscreen = toggle ? !fullScreen() : fullScreen(); - msg << "Fullscreen "; - if(isFullscreen) - msg << "enabled (" << refreshRate() << " Hz)"; - else - msg << "disabled"; + setFullscreen(isFullscreen); - showMessage(msg.str()); + if (myBufferType != BufferType::Launcher) + { + ostringstream msg; + + msg << "Fullscreen "; + if (isFullscreen) + msg << "enabled (" << refreshRate() << " Hz)"; + else + msg << "disabled"; + + showMessage(msg.str()); + } + break; + } + default: + break; } } From 379dfe4ac374974c2dd85fb63d322caa09a0e4d5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 2 Jul 2020 17:28:48 -0230 Subject: [PATCH 101/104] Refactor Cart::getImage, always return a ByteBuffer. Most classes did this already, but some didn't. So we standardize on this, and eliminate raw pointers. --- src/debugger/gui/Cart3EPlusWidget.cxx | 4 +-- src/debugger/gui/Cart3EWidget.cxx | 2 +- src/debugger/gui/Cart3FWidget.cxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 2 +- src/emucore/Cart.cxx | 6 ++-- src/emucore/Cart.hxx | 4 +-- src/emucore/Cart4A50.cxx | 9 +++--- src/emucore/Cart4A50.hxx | 6 ++-- src/emucore/CartAR.cxx | 4 +-- src/emucore/CartAR.hxx | 4 +-- src/emucore/CartBUS.cxx | 19 ++++++------ src/emucore/CartBUS.hxx | 6 ++-- src/emucore/CartCDF.cxx | 20 +++++++------ src/emucore/CartCDF.hxx | 6 ++-- src/emucore/CartCM.cxx | 13 ++++---- src/emucore/CartCM.hxx | 6 ++-- src/emucore/CartCTY.cxx | 17 ++++++----- src/emucore/CartCTY.hxx | 6 ++-- src/emucore/CartDPCPlus.cxx | 21 ++++++------- src/emucore/CartDPCPlus.hxx | 6 ++-- src/emucore/CartEnhanced.cxx | 4 +-- src/emucore/CartEnhanced.hxx | 4 +-- src/emucore/CartF6.cxx | 1 - src/emucore/CartMNetwork.cxx | 4 +-- src/emucore/CartMNetwork.hxx | 4 +-- src/emucore/Console.cxx | 2 +- src/emucore/ControllerDetector.cxx | 31 ++++++++++--------- src/emucore/ControllerDetector.hxx | 40 ++++++++++++++----------- src/gui/GameInfoDialog.cxx | 4 +-- src/gui/RomInfoWidget.cxx | 4 +-- src/gui/StellaSettingsDialog.cxx | 4 +-- 31 files changed, 139 insertions(+), 126 deletions(-) diff --git a/src/debugger/gui/Cart3EPlusWidget.cxx b/src/debugger/gui/Cart3EPlusWidget.cxx index 163dc23fd..cd0fda251 100644 --- a/src/debugger/gui/Cart3EPlusWidget.cxx +++ b/src/debugger/gui/Cart3EPlusWidget.cxx @@ -35,7 +35,7 @@ string Cartridge3EPlusWidget::description() { ostringstream info; size_t size; - const uInt8* image = myCart.getImage(size); + const ByteBuffer& image = myCart.getImage(size); uInt16 numRomBanks = myCart.romBankCount(); uInt16 numRamBanks = myCart.ramBankCount(); @@ -60,7 +60,7 @@ string Cartridge3EPlusWidget::description() void Cartridge3EPlusWidget::bankSelect(int& ypos) { size_t size; - const uInt8* image = myCart.getImage(size); + const ByteBuffer& image = myCart.getImage(size); const int VGAP = myFontHeight / 4; VariantList banktype; diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index 4683ea7d4..910f03368 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -33,7 +33,7 @@ string Cartridge3EWidget::description() { ostringstream info; size_t size; - const uInt8* image = myCart.getImage(size); + const ByteBuffer& image = myCart.getImage(size); uInt16 numRomBanks = myCart.romBankCount(); uInt16 numRamBanks = myCart.ramBankCount(); diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index ff5b0d219..a84f0fd4f 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -33,7 +33,7 @@ string Cartridge3FWidget::description() { ostringstream info; size_t size; - const uInt8* image = myCart.getImage(size); + const ByteBuffer& image = myCart.getImage(size); info << "Tigervision 3F cartridge, 2 - 256 2K banks\n" << "First 2K bank selected by writing to " << hotspotStr() << "\n" diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index af110cb0d..97beb1f6b 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -94,7 +94,7 @@ string CartridgeEnhancedWidget::romDescription() { ostringstream info; size_t size; - const uInt8* image = myCart.getImage(size); + const ByteBuffer& image = myCart.getImage(size); if(myCart.romBankCount() > 1) { diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index 958b915df..045d4c784 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -56,14 +56,14 @@ bool Cartridge::saveROM(ofstream& out) const { size_t size = 0; - const uInt8* image = getImage(size); - if(image == nullptr || size == 0) + const ByteBuffer& image = getImage(size); + if(size == 0) { cerr << "save not supported" << endl; return false; } - out.write(reinterpret_cast(image), size); + out.write(reinterpret_cast(image.get()), size); return true; } diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 0e70f4bf7..8ccd10d79 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -229,9 +229,9 @@ class Cartridge : public Device Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - virtual const uInt8* getImage(size_t& size) const = 0; + virtual const ByteBuffer& getImage(size_t& size) const = 0; /** Get a descriptor for the cart name. diff --git a/src/emucore/Cart4A50.cxx b/src/emucore/Cart4A50.cxx index 845229bc4..6939bc0ef 100644 --- a/src/emucore/Cart4A50.cxx +++ b/src/emucore/Cart4A50.cxx @@ -24,6 +24,7 @@ Cartridge4A50::Cartridge4A50(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : Cartridge(settings, md5), + myImage(make_unique(128_KB)), mySize(size) { // Copy the ROM image into my buffer @@ -32,7 +33,7 @@ Cartridge4A50::Cartridge4A50(const ByteBuffer& image, size_t size, else if(size < 128_KB) size = 64_KB; else size = 128_KB; for(uInt32 slice = 0; slice < 128_KB / size; ++slice) - std::copy_n(image.get(), size, myImage.begin() + (slice*size)); + std::copy_n(image.get(), size, myImage.get() + (slice*size)); // We use System::PageAccess.romAccessBase, but don't allow its use // through a pointer, since the address space of 4A50 carts can change @@ -41,7 +42,7 @@ Cartridge4A50::Cartridge4A50(const ByteBuffer& image, size_t size, // // Instead, access will be through the getAccessFlags and setAccessFlags // methods below - createRomAccessArrays(myImage.size() + myRAM.size()); + createRomAccessArrays(128_KB + myRAM.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -350,10 +351,10 @@ bool Cartridge4A50::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge4A50::getImage(size_t& size) const +const ByteBuffer& Cartridge4A50::getImage(size_t& size) const { size = mySize; - return myImage.data(); + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart4A50.hxx b/src/emucore/Cart4A50.hxx index e68bb8f4a..8a4fdaa2d 100644 --- a/src/emucore/Cart4A50.hxx +++ b/src/emucore/Cart4A50.hxx @@ -96,9 +96,9 @@ class Cartridge4A50 : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -220,7 +220,7 @@ class Cartridge4A50 : public Cartridge private: // The 128K ROM image of the cartridge - std::array myImage; + ByteBuffer myImage; // The 32K of RAM on the cartridge std::array myRAM; diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index 08f803e0b..cc58d60be 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -420,10 +420,10 @@ bool CartridgeAR::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeAR::getImage(size_t& size) const +const ByteBuffer& CartridgeAR::getImage(size_t& size) const { size = mySize; - return myLoadImages.get(); + return myLoadImages; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 349de38f1..0b4369f31 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -105,9 +105,9 @@ class CartridgeAR : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index 62000118b..46d220bbf 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -43,17 +43,18 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : Cartridge(settings, md5), + myImage(make_unique(32_KB)) { // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); + std::copy_n(image.get(), std::min(32_KB, size), myImage.get()); // Even though the ROM is 32K, only 28K is accessible to the 6507 createRomAccessArrays(28_KB); // Pointer to the program ROM (28K @ 0 byte offset) // which starts after the 2K BUS Driver and 2K C Code - myProgramImage = myImage.data() + 4_KB; + myProgramImage = myImage.get() + 4_KB; // Pointer to BUS driver in RAM myDriverImage = myRAM.data(); @@ -64,9 +65,9 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size, // Create Thumbulator ARM emulator bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique( - reinterpret_cast(myImage.data()), + reinterpret_cast(myImage.get()), reinterpret_cast(myRAM.data()), - static_cast(myImage.size()), + static_cast(32_KB), devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::BUS, this ); @@ -95,7 +96,7 @@ void CartridgeBUS::reset() void CartridgeBUS::setInitialState() { // Copy initial BUS driver to Harmony RAM - std::copy_n(myImage.begin(), 2_KB, myDriverImage); + std::copy_n(myImage.get(), 2_KB, myDriverImage); myMusicWaveformSize.fill(27); @@ -478,10 +479,10 @@ bool CartridgeBUS::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeBUS::getImage(size_t& size) const +const ByteBuffer& CartridgeBUS::getImage(size_t& size) const { - size = myImage.size(); - return myImage.data(); + size = 32_KB; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 58e4eea48..2e21b5f24 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -116,9 +116,9 @@ class CartridgeBUS : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -214,7 +214,7 @@ class CartridgeBUS : public Cartridge private: // The 32K ROM image of the cartridge - std::array myImage; + ByteBuffer myImage; // Pointer to the 28K program ROM image of the cartridge uInt8* myProgramImage{nullptr}; diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 09e0da3e3..e09480464 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -59,17 +59,19 @@ namespace { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : Cartridge(settings, md5), + myImage(make_unique(32_KB)) { // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); + std::fill_n(myImage.get(), 32_KB, 0); + std::copy_n(image.get(), std::min(32_KB, size), myImage.get()); // even though the ROM is 32K, only 28K is accessible to the 6507 createRomAccessArrays(28_KB); // Pointer to the program ROM (28K @ 0 byte offset) // which starts after the 2K CDF Driver and 2K C Code - myProgramImage = myImage.data() + 4_KB; + myProgramImage = myImage.get() + 4_KB; // Pointer to CDF driver in RAM myDriverImage = myRAM.data(); @@ -82,9 +84,9 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, // Create Thumbulator ARM emulator bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique( - reinterpret_cast(myImage.data()), + reinterpret_cast(myImage.get()), reinterpret_cast(myRAM.data()), - static_cast(myImage.size()), + static_cast(32_KB), devSettings ? settings.getBool("dev.thumb.trapfatal") : false, thumulatorConfiguration(myCDFSubtype), this); setInitialState(); @@ -111,7 +113,7 @@ void CartridgeCDF::reset() void CartridgeCDF::setInitialState() { // Copy initial CDF driver to Harmony RAM - std::copy_n(myImage.begin(), 2_KB, myDriverImage); + std::copy_n(myImage.get(), 2_KB, myDriverImage); myMusicWaveformSize.fill(27); @@ -451,10 +453,10 @@ bool CartridgeCDF::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeCDF::getImage(size_t& size) const +const ByteBuffer& CartridgeCDF::getImage(size_t& size) const { - size = myImage.size(); - return myImage.data(); + size = 32_KB; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 62c1721ca..99374de2b 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -122,9 +122,9 @@ class CartridgeCDF : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -214,7 +214,7 @@ class CartridgeCDF : public Cartridge private: // The 32K ROM image of the cartridge - std::array myImage; + ByteBuffer myImage; // Pointer to the 28K program ROM image of the cartridge uInt8* myProgramImage{nullptr}; diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index b5dfc5197..dbaac7a54 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -23,11 +23,12 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCM::CartridgeCM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : Cartridge(settings, md5), + myImage(make_unique(16_KB)) { // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + std::copy_n(image.get(), std::min(16_KB, size), myImage.get()); + createRomAccessArrays(16_KB); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -184,10 +185,10 @@ bool CartridgeCM::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeCM::getImage(size_t& size) const +const ByteBuffer& CartridgeCM::getImage(size_t& size) const { - size = myImage.size(); - return myImage.data(); + size = 16_KB; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index 36fa13fa8..3a58889b4 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -173,9 +173,9 @@ class CartridgeCM : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -246,7 +246,7 @@ class CartridgeCM : public Cartridge shared_ptr myCompuMate; // The 16K ROM image of the cartridge - std::array myImage; + ByteBuffer myImage; // The 2K of RAM std::array myRAM; diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index dbb5d13e2..67647f89c 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -24,18 +24,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCTY::CartridgeCTY(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : Cartridge(settings, md5), + myImage(make_unique(32_KB)) { // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + std::copy_n(image.get(), std::min(32_KB, size), myImage.get()); + createRomAccessArrays(32_KB); // Default to no tune data in case user is utilizing an old ROM myTuneData.fill(0); // Extract tune data if it exists - if(size > myImage.size()) - std::copy_n(image.get() + myImage.size(), size - myImage.size(), myTuneData.begin()); + if(size > 32_KB) + std::copy_n(image.get() + 32_KB, size - 32_KB, myTuneData.begin()); // Point to the first tune myFrequencyImage = myTuneData.data(); @@ -279,10 +280,10 @@ bool CartridgeCTY::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeCTY::getImage(size_t& size) const +const ByteBuffer& CartridgeCTY::getImage(size_t& size) const { - size = myImage.size(); - return myImage.data(); + size = 32_KB; + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index 1cd682446..5af3ceff4 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -171,9 +171,9 @@ class CartridgeCTY : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -263,7 +263,7 @@ class CartridgeCTY : public Cartridge private: // The 32K ROM image of the cartridge - std::array myImage; + ByteBuffer myImage; // The 28K ROM image of the music std::array myTuneData; diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 7a0a7f4c6..71500ee94 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -29,17 +29,18 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : Cartridge(settings, md5), - mySize(std::min(size, myImage.size())) + myImage(make_unique(32_KB)), + mySize(std::min(size, 32_KB)) { - // Image is always 32K, but in the case of ROM > 29K, the image is + // Image is always 32K, but in the case of ROM < 32K, the image is // copied to the end of the buffer - if(mySize < myImage.size()) - myImage.fill(0); - std::copy_n(image.get(), size, myImage.begin() + (myImage.size() - mySize)); + if(mySize < 32_KB) + std::fill_n(myImage.get(), mySize, 0); + std::copy_n(image.get(), size, myImage.get() + (32_KB - mySize)); createRomAccessArrays(24_KB); // Pointer to the program ROM (24K @ 3K offset; ignore first 3K) - myProgramImage = myImage.data() + 3_KB; + myProgramImage = myImage.get() + 3_KB; // Pointer to the display RAM myDisplayImage = myDPCRAM.data() + 3_KB; @@ -50,9 +51,9 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size, // Create Thumbulator ARM emulator bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique - (reinterpret_cast(myImage.data()), + (reinterpret_cast(myImage.get()), reinterpret_cast(myDPCRAM.data()), - static_cast(myImage.size()), + static_cast(32_KB), devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::DPCplus, this); @@ -640,10 +641,10 @@ bool CartridgeDPCPlus::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeDPCPlus::getImage(size_t& size) const +const ByteBuffer& CartridgeDPCPlus::getImage(size_t& size) const { size = mySize; - return myImage.data() + (myImage.size() - mySize); + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index bbbf68197..04a1b0de4 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -118,9 +118,9 @@ class CartridgeDPCPlus : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. @@ -203,7 +203,7 @@ class CartridgeDPCPlus : public Cartridge private: // The ROM image and size - std::array myImage; + ByteBuffer myImage; size_t mySize{0}; // Pointer to the 24K program ROM image of the cartridge diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 28b8b026c..633104cf3 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -364,10 +364,10 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeEnhanced::getImage(size_t& size) const +const ByteBuffer& CartridgeEnhanced::getImage(size_t& size) const { size = mySize; - return myImage.get(); + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index c50f88aa6..e99afc917 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -120,9 +120,9 @@ class CartridgeEnhanced : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 0e4bcf678..7b120d0b0 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -37,4 +37,3 @@ bool CartridgeF6::checkSwitchBank(uInt16 address, uInt8) } return false; } - diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index 84cf8dac8..78c68e6a0 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -263,10 +263,10 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeMNetwork::getImage(size_t& size) const +const ByteBuffer& CartridgeMNetwork::getImage(size_t& size) const { size = romBankCount() * BANK_SIZE; - return myImage.get(); + return myImage; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index 7b4fdb729..9b17a4b67 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -126,9 +126,9 @@ class CartridgeMNetwork : public Cartridge Access the internal ROM image for this cartridge. @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data + @return A reference to the internal ROM image data */ - const uInt8* getImage(size_t& size) const override; + const ByteBuffer& getImage(size_t& size) const override; /** Save the current state of this cart to the given Serializer. diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 1e796a0bd..e6afa0aa4 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -726,7 +726,7 @@ void Console::setControllers(const string& romMd5) Controller::Type leftType = Controller::getType(myProperties.get(PropType::Controller_Left)); Controller::Type rightType = Controller::getType(myProperties.get(PropType::Controller_Right)); size_t size = 0; - const uInt8* image = myCart->getImage(size); + const ByteBuffer& image = myCart->getImage(size); const bool swappedPorts = myProperties.get(PropType::Console_SwapPorts) == "YES"; // Try to detect controllers diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 6609340df..95922051b 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -22,8 +22,10 @@ #include "ControllerDetector.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Controller::Type ControllerDetector::detectType(const uInt8* image, size_t size, - const Controller::Type type, const Controller::Jack port, const Settings& settings) +Controller::Type ControllerDetector::detectType( + const ByteBuffer& image, size_t size, + const Controller::Type type, const Controller::Jack port, + const Settings& settings) { if(type == Controller::Type::Unknown || settings.getBool("rominfo")) { @@ -43,7 +45,7 @@ Controller::Type ControllerDetector::detectType(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerDetector::detectName(const uInt8* image, size_t size, +string ControllerDetector::detectName(const ByteBuffer& image, size_t size, const Controller::Type controller, const Controller::Jack port, const Settings& settings) { @@ -51,7 +53,8 @@ string ControllerDetector::detectName(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Controller::Type ControllerDetector::autodetectPort(const uInt8* image, size_t size, +Controller::Type ControllerDetector::autodetectPort( + const ByteBuffer& image, size_t size, Controller::Jack port, const Settings& settings) { // default type joystick @@ -88,7 +91,7 @@ Controller::Type ControllerDetector::autodetectPort(const uInt8* image, size_t s } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::searchForBytes(const uInt8* image, size_t imagesize, +bool ControllerDetector::searchForBytes(const ByteBuffer& image, size_t imagesize, const uInt8* signature, uInt32 sigsize) { if (imagesize >= sigsize) @@ -112,7 +115,7 @@ bool ControllerDetector::searchForBytes(const uInt8* image, size_t imagesize, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::usesJoystickButton(const uInt8* image, size_t size, +bool ControllerDetector::usesJoystickButton(const ByteBuffer& image, size_t size, Controller::Jack port) { if(port == Controller::Jack::Left) @@ -242,7 +245,7 @@ bool ControllerDetector::usesJoystickButton(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::usesKeyboard(const uInt8* image, size_t size, +bool ControllerDetector::usesKeyboard(const ByteBuffer& image, size_t size, Controller::Jack port) { if(port == Controller::Jack::Left) @@ -383,7 +386,7 @@ bool ControllerDetector::usesKeyboard(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::usesGenesisButton(const uInt8* image, size_t size, +bool ControllerDetector::usesGenesisButton(const ByteBuffer& image, size_t size, Controller::Jack port) { if(port == Controller::Jack::Left) @@ -440,7 +443,7 @@ bool ControllerDetector::usesGenesisButton(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::usesPaddle(const uInt8* image, size_t size, +bool ControllerDetector::usesPaddle(const ByteBuffer& image, size_t size, Controller::Jack port, const Settings& settings) { if(port == Controller::Jack::Left) @@ -549,7 +552,7 @@ bool ControllerDetector::usesPaddle(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::isProbablyTrakBall(const uInt8* image, size_t size) +bool ControllerDetector::isProbablyTrakBall(const ByteBuffer& image, size_t size) { // check for TrakBall tables const int NUM_SIGS = 3; @@ -568,7 +571,7 @@ bool ControllerDetector::isProbablyTrakBall(const uInt8* image, size_t size) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::isProbablyAtariMouse(const uInt8* image, size_t size) +bool ControllerDetector::isProbablyAtariMouse(const ByteBuffer& image, size_t size) { // check for Atari Mouse tables const int NUM_SIGS = 3; @@ -587,7 +590,7 @@ bool ControllerDetector::isProbablyAtariMouse(const uInt8* image, size_t size) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::isProbablyAmigaMouse(const uInt8* image, size_t size) +bool ControllerDetector::isProbablyAmigaMouse(const ByteBuffer& image, size_t size) { // check for Amiga Mouse tables const int NUM_SIGS = 4; @@ -607,7 +610,7 @@ bool ControllerDetector::isProbablyAmigaMouse(const uInt8* image, size_t size) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::isProbablySaveKey(const uInt8* image, size_t size, +bool ControllerDetector::isProbablySaveKey(const ByteBuffer& image, size_t size, Controller::Jack port) { // check for known SaveKey code, only supports right port @@ -652,7 +655,7 @@ bool ControllerDetector::isProbablySaveKey(const uInt8* image, size_t size, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerDetector::isProbablyLightGun(const uInt8* image, size_t size, +bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size, Controller::Jack port) { if (port == Controller::Jack::Left) diff --git a/src/emucore/ControllerDetector.hxx b/src/emucore/ControllerDetector.hxx index d37076eb1..be24ae09d 100644 --- a/src/emucore/ControllerDetector.hxx +++ b/src/emucore/ControllerDetector.hxx @@ -34,14 +34,14 @@ class ControllerDetector /** Detects the controller type at the given port if no controller is provided. - @param image A pointer to the ROM image + @param image A reference to the ROM image @param size The size of the ROM image @param controller The provided controller type of the ROM image @param port The port to be checked @param settings A reference to the various settings (read-only) @return The detected controller type */ - static Controller::Type detectType(const uInt8* image, size_t size, + static Controller::Type detectType(const ByteBuffer& image, size_t size, const Controller::Type controller, const Controller::Jack port, const Settings& settings); @@ -49,7 +49,7 @@ class ControllerDetector Detects the controller type at the given port if no controller is provided and returns its name. - @param image A pointer to the ROM image + @param image A reference to the ROM image @param size The size of the ROM image @param type The provided controller type of the ROM image @param port The port to be checked @@ -57,7 +57,7 @@ class ControllerDetector @return The (detected) controller name */ - static string detectName(const uInt8* image, size_t size, + static string detectName(const ByteBuffer& image, size_t size, const Controller::Type type, const Controller::Jack port, const Settings& settings); @@ -65,14 +65,14 @@ class ControllerDetector /** Detects the controller type at the given port. - @param image A pointer to the ROM image + @param image A reference to the ROM image @param size The size of the ROM image @param port The port to be checked @param settings A reference to the various settings (read-only) @return The detected controller type */ - static Controller::Type autodetectPort(const uInt8* image, size_t size, + static Controller::Type autodetectPort(const ByteBuffer& image, size_t size, Controller::Jack port, const Settings& settings); /** @@ -85,36 +85,41 @@ class ControllerDetector @return True if the signature was found, else false */ - static bool searchForBytes(const uInt8* image, size_t imagesize, + static bool searchForBytes(const ByteBuffer& image, size_t imagesize, const uInt8* signature, uInt32 sigsize); // Returns true if the port's joystick button access code is found. - static bool usesJoystickButton(const uInt8* image, size_t size, Controller::Jack port); + static bool usesJoystickButton(const ByteBuffer& image, size_t size, + Controller::Jack port); // Returns true if the port's keyboard access code is found. - static bool usesKeyboard(const uInt8* image, size_t size, Controller::Jack port); + static bool usesKeyboard(const ByteBuffer& image, size_t size, + Controller::Jack port); // Returns true if the port's 2nd Genesis button access code is found. - static bool usesGenesisButton(const uInt8* image, size_t size, Controller::Jack port); + static bool usesGenesisButton(const ByteBuffer& image, size_t size, + Controller::Jack port); // Returns true if the port's paddle button access code is found. - static bool usesPaddle(const uInt8* image, size_t size, Controller::Jack port, - const Settings& settings); + static bool usesPaddle(const ByteBuffer& image, size_t size, + Controller::Jack port, const Settings& settings); // Returns true if a Trak-Ball table is found. - static bool isProbablyTrakBall(const uInt8* image, size_t size); + static bool isProbablyTrakBall(const ByteBuffer& image, size_t size); // Returns true if an Atari Mouse table is found. - static bool isProbablyAtariMouse(const uInt8* image, size_t size); + static bool isProbablyAtariMouse(const ByteBuffer& image, size_t size); // Returns true if an Amiga Mouse table is found. - static bool isProbablyAmigaMouse(const uInt8* image, size_t size); + static bool isProbablyAmigaMouse(const ByteBuffer& image, size_t size); // Returns true if a SaveKey code pattern is found. - static bool isProbablySaveKey(const uInt8* image, size_t size, Controller::Jack port); + static bool isProbablySaveKey(const ByteBuffer& image, size_t size, + Controller::Jack port); // Returns true if a Lightgun code pattern is found - static bool isProbablyLightGun(const uInt8* image, size_t size, Controller::Jack port); + static bool isProbablyLightGun(const ByteBuffer& image, size_t size, + Controller::Jack port); private: @@ -127,4 +132,3 @@ class ControllerDetector }; #endif - diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 2348e047d..ff1fca0c6 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -707,7 +707,7 @@ void GameInfoDialog::updateControllerStates() label = (!swapPorts ? instance().console().leftController().name() : instance().console().rightController().name()) + " detected"; else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, type, + label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, instance().settings()) + " detected"; } @@ -722,7 +722,7 @@ void GameInfoDialog::updateControllerStates() label = (!swapPorts ? instance().console().rightController().name() : instance().console().leftController().name()) + " detected"; else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, type, + label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, instance().settings()) + " detected"; } diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index 3cfa43185..b90a45fb2 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -152,10 +152,10 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) (image = instance().openROM(node, md5, size)) != nullptr) { Logger::debug(myProperties.get(PropType::Cart_Name) + ":"); - left = ControllerDetector::detectName(image.get(), size, leftType, + left = ControllerDetector::detectName(image, size, leftType, !swappedPorts ? Controller::Jack::Left : Controller::Jack::Right, instance().settings()); - right = ControllerDetector::detectName(image.get(), size, rightType, + right = ControllerDetector::detectName(image, size, rightType, !swappedPorts ? Controller::Jack::Right : Controller::Jack::Left, instance().settings()); if (bsDetected == "AUTO") diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index b5c1e5106..74e8ca35f 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -540,7 +540,7 @@ void StellaSettingsDialog::updateControllerStates() if(instance().hasConsole()) label = (instance().console().leftController().name()) + " detected"; else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, type, + label = ControllerDetector::detectName(image, size, type, Controller::Jack::Left, instance().settings()) + " detected"; } @@ -554,7 +554,7 @@ void StellaSettingsDialog::updateControllerStates() if(instance().hasConsole()) label = (instance().console().rightController().name()) + " detected"; else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, type, + label = ControllerDetector::detectName(image, size, type, Controller::Jack::Right, instance().settings()) + " detected"; } From 8f2f13b0dccb18045a746b211f106c065c08e4b1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 2 Jul 2020 23:33:13 +0200 Subject: [PATCH 102/104] Added global hot keys for debug options --- Changes.txt | 1 + docs/index.html | 99 +++++++------ src/common/PKeyboardHandler.cxx | 4 + src/emucore/Console.cxx | 47 +++--- src/emucore/Console.hxx | 40 ++--- src/emucore/Event.hxx | 3 +- src/emucore/EventHandler.cxx | 250 +++++++++++++++++++++++++++----- src/emucore/EventHandler.hxx | 41 +++++- src/emucore/FrameBuffer.cxx | 8 +- src/emucore/FrameBuffer.hxx | 2 +- src/emucore/tia/TIA.cxx | 27 +++- src/emucore/tia/TIA.hxx | 12 +- 12 files changed, 393 insertions(+), 141 deletions(-) diff --git a/Changes.txt b/Changes.txt index 65b7dbec1..cc1ca3b3b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -16,6 +16,7 @@ * Added new interface palette 'Dark'. (TODO: DOC) + * Extended global hotkeys for debug options. 6.2 to 6.2.1: (June 20, 2020) diff --git a/docs/index.html b/docs/index.html index 276fbae1b..bc3f46f29 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1430,7 +1430,7 @@
- These settings can also be changed using Global Audio & Video Keys
+ These settings can also be changed using Global Keys @@ -1480,7 +1480,7 @@
- These settings can also be changed using Global Audio & Video Keys
+ These settings can also be changed using Global Keys @@ -1550,7 +1550,7 @@
- These settings can also be changed using Global Audio & Video Keys
+ These settings can also be changed using Global Keys @@ -1559,45 +1559,6 @@ -

Global Audio & Video Keys (can be remapped)

-

These keys allow selecting and changing audio & video settings without having to remember the - dedicated keys.

- - - - - - - - - - - - - - - - - - - - - - - - - -
FunctionKey (Standard)Key (macOS)
Select previous AV settingEndFn + Left arrow
Select next AV settingHomeFn + Right arrow
Decrease current AV settingPageDownFn + Down arrow
Increase current AV setting - PageUpFn + Up arrow
-

Notes: -

    -
  • Only available if UI messages are enabled.
  • -
  • Currently not available settings are automatically skipped.
  • -
  • If a setting was selected via dedicated key, its value can also be changed with the - global keys.
  • -
-


-

Developer Keys (can be remapped)

@@ -1715,8 +1676,62 @@ Alt + j Cmd + j + +
+ These settings can also be changed using Global Keys
+ + +

Global Keys (can be remapped)

+

These keys allow selecting and changing settings without having to remember the + dedicated keys. They keys are grouped by Audio & Video and Debug settings.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionKey (Standard)Key (macOS)
Select previous setting groupControl + EndControl-Fn + Left arrow
Select next setting groupControl + HomeControl-Fn + Right arrow
Select previous settingEndFn + Left arrow
Select next settingHomeFn + Right arrow
Decrease current settingPageDownFn + Down arrow
Increase current setting + PageUpFn + Up arrow
+

Notes: +

    +
  • Only available if UI messages are enabled.
  • +
  • Currently not available settings are automatically skipped.
  • +
  • If a setting was selected via dedicated key, its value can also be changed with the + global keys.
  • +
+

+

Other Emulation Keys (can be remapped)

diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 4ff5191fb..59beffdac 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -505,9 +505,13 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo #ifndef BSPF_MACOS {Event::PreviousSetting, KBDK_END}, {Event::NextSetting, KBDK_HOME}, + {Event::PreviousSettingGroup, KBDK_END, KBDM_CTRL}, + {Event::NextSettingGroup, KBDK_HOME, KBDM_CTRL}, #else {Event::PreviousSetting, KBDK_HOME}, {Event::NextSetting, KBDK_END}, + {Event::PreviousSettingGroup, KBDK_HOME, KBDM_CTRL}, + {Event::NextSettingGroup, KBDK_END, KBDM_CTRL}, #endif {Event::SettingDecrease, KBDK_PAGEDOWN}, {Event::SettingIncrease, KBDK_PAGEUP}, diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index e6afa0aa4..1f828ee94 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -444,7 +444,7 @@ void Console::setFormat(uInt32 format, bool force) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleColorLoss() +void Console::toggleColorLoss(bool toggle) { bool colorloss = !myTIA->colorLossEnabled(); if(myTIA->enableColorLoss(colorloss)) @@ -876,51 +876,56 @@ float Console::getFramerate() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleTIABit(TIABit bit, const string& bitname, bool show) const +void Console::toggleTIABit(TIABit bit, const string& bitname, bool show, bool toggle) const { - bool result = myTIA->toggleBit(bit); - string message = bitname + (result ? " enabled" : " disabled"); + bool result = myTIA->toggleBit(bit, toggle ? 2 : 3); + const string message = bitname + (result ? " enabled" : " disabled"); + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleBits() const +void Console::toggleBits(bool toggle) const { - bool enabled = myTIA->toggleBits(); - string message = string("TIA bits") + (enabled ? " enabled" : " disabled"); + bool enabled = myTIA->toggleBits(toggle); + const string message = string("TIA bits ") + (enabled ? "enabled" : "disabled"); + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show) const +void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show, bool toggle) const { - bool result = myTIA->toggleCollision(bit); - string message = bitname + (result ? " collision enabled" : " collision disabled"); + bool result = myTIA->toggleCollision(bit, toggle ? 2 : 3); + const string message = bitname + (result ? " collision enabled" : " collision disabled"); + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleCollisions() const +void Console::toggleCollisions(bool toggle) const { - bool enabled = myTIA->toggleCollisions(); - string message = string("TIA collisions") + (enabled ? " enabled" : " disabled"); + bool enabled = myTIA->toggleCollisions(toggle); + const string message = string("TIA collisions ") + (enabled ? "enabled" : "disabled"); + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleFixedColors() const +void Console::toggleFixedColors(bool toggle) const { - if(myTIA->toggleFixedColors()) - myOSystem.frameBuffer().showMessage("Fixed debug colors enabled"); - else - myOSystem.frameBuffer().showMessage("Fixed debug colors disabled"); + bool enabled = toggle ? myTIA->toggleFixedColors() : myTIA->usingFixedColors(); + const string message = string("Fixed debug colors ") + (enabled ? "enabled" : "disabled"); + + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Console::toggleJitter() const +void Console::toggleJitter(bool toggle) const { - bool enabled = myTIA->toggleJitter(); - string message = string("TV scanline jitter") + (enabled ? " enabled" : " disabled"); + bool enabled = myTIA->toggleJitter(toggle ? 2 : 3); + const string message = string("TV scanline jitter ") + (enabled ? "enabled" : "disabled"); + myOSystem.frameBuffer().showMessage(message); } diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index d13588b07..1cc37fc0b 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -229,7 +229,7 @@ class Console : public Serializable, public ConsoleIO /** Toggles the PAL color-loss effect. */ - void toggleColorLoss(); + void toggleColorLoss(bool toggle = true); void enableColorLoss(bool state); /** @@ -278,34 +278,34 @@ class Console : public Serializable, public ConsoleIO /** Toggles the TIA bit specified in the method name. */ - void toggleP0Bit() const { toggleTIABit(P0Bit, "P0"); } - void toggleP1Bit() const { toggleTIABit(P1Bit, "P1"); } - void toggleM0Bit() const { toggleTIABit(M0Bit, "M0"); } - void toggleM1Bit() const { toggleTIABit(M1Bit, "M1"); } - void toggleBLBit() const { toggleTIABit(BLBit, "BL"); } - void togglePFBit() const { toggleTIABit(PFBit, "PF"); } - void toggleBits() const; + void toggleP0Bit(bool toggle = true) const { toggleTIABit(P0Bit, "P0", true, toggle); } + void toggleP1Bit(bool toggle = true) const { toggleTIABit(P1Bit, "P1", true, toggle); } + void toggleM0Bit(bool toggle = true) const { toggleTIABit(M0Bit, "M0", true, toggle); } + void toggleM1Bit(bool toggle = true) const { toggleTIABit(M1Bit, "M1", true, toggle); } + void toggleBLBit(bool toggle = true) const { toggleTIABit(BLBit, "BL", true, toggle); } + void togglePFBit(bool toggle = true) const { toggleTIABit(PFBit, "PF", true, toggle); } + void toggleBits(bool toggle = true) const; /** Toggles the TIA collisions specified in the method name. */ - void toggleP0Collision() const { toggleTIACollision(P0Bit, "P0"); } - void toggleP1Collision() const { toggleTIACollision(P1Bit, "P1"); } - void toggleM0Collision() const { toggleTIACollision(M0Bit, "M0"); } - void toggleM1Collision() const { toggleTIACollision(M1Bit, "M1"); } - void toggleBLCollision() const { toggleTIACollision(BLBit, "BL"); } - void togglePFCollision() const { toggleTIACollision(PFBit, "PF"); } - void toggleCollisions() const; + void toggleP0Collision(bool toggle = true) const { toggleTIACollision(P0Bit, "P0", true, toggle); } + void toggleP1Collision(bool toggle = true) const { toggleTIACollision(P1Bit, "P1", true, toggle); } + void toggleM0Collision(bool toggle = true) const { toggleTIACollision(M0Bit, "M0", true, toggle); } + void toggleM1Collision(bool toggle = true) const { toggleTIACollision(M1Bit, "M1", true, toggle); } + void toggleBLCollision(bool toggle = true) const { toggleTIACollision(BLBit, "BL", true, toggle); } + void togglePFCollision(bool toggle = true) const { toggleTIACollision(PFBit, "PF", true, toggle); } + void toggleCollisions(bool toggle = true) const; /** Toggles the TIA 'fixed debug colors' mode. */ - void toggleFixedColors() const; + void toggleFixedColors(bool toggle = true) const; /** Toggles the TIA 'scanline jitter' mode. */ - void toggleJitter() const; + void toggleJitter(bool toggle = true) const; /** * Update vcenter @@ -351,8 +351,10 @@ class Console : public Serializable, public ConsoleIO unique_ptr getControllerPort(const Controller::Type type, const Controller::Jack port, const string& romMd5); - void toggleTIABit(TIABit bit, const string& bitname, bool show = true) const; - void toggleTIACollision(TIABit bit, const string& bitname, bool show = true) const; + void toggleTIABit(TIABit bit, const string& bitname, + bool show = true, bool toggle = true) const; + void toggleTIACollision(TIABit bit, const string& bitname, + bool show = true, bool toggle = true) const; private: // Reference to the osystem object diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 9a6c16352..f666e19bc 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -121,9 +121,10 @@ class Event ToggleCollisions, ToggleBits, ToggleFixedColors, ToggleFrameStats, ToggleSAPortOrder, ExitGame, - // add new events from here to avoid that user remapped events get overwritten SettingDecrease, SettingIncrease, PreviousSetting, NextSetting, ToggleAdaptRefresh, PreviousMultiCartRom, + // add new events from here to avoid that user remapped events get overwritten + PreviousSettingGroup, NextSettingGroup, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 23a9c98ee..53b1eee7a 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -342,6 +342,16 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int) } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EventHandler::AdjustGroup EventHandler::getAdjustGroup() +{ + if (myAdjustSetting >= AdjustSetting::START_DEBUG_ADJ && myAdjustSetting <= AdjustSetting::END_DEBUG_ADJ) + return AdjustGroup::DEBUG; + + return AdjustGroup::AV; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AdjustFunction EventHandler::cycleAdjustSetting(int direction) { @@ -350,21 +360,38 @@ AdjustFunction EventHandler::cycleAdjustSetting(int direction) myOSystem.settings().getString("palette") == PaletteHandler::SETTING_CUSTOM; const bool isCustomFilter = myOSystem.settings().getInt("tv.filter") == int(NTSCFilter::Preset::CUSTOM); - bool repeat; + const bool isPAL = myOSystem.console().timing() == ConsoleTiming::pal; + bool repeat = false; do { - myAdjustSetting = - AdjustSetting(BSPF::clampw(int(myAdjustSetting) + direction, 0, int(AdjustSetting::MAX_ADJ))); - // skip currently non-relevant adjustments - repeat = (myAdjustSetting == AdjustSetting::OVERSCAN && !isFullScreen) - #ifdef ADAPTABLE_REFRESH_SUPPORT - || (myAdjustSetting == AdjustSetting::ADAPT_REFRESH && !isFullScreen) - #endif - || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette) - || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS - && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING - && !isCustomFilter); + switch (getAdjustGroup()) + { + case AdjustGroup::AV: + myAdjustSetting = + AdjustSetting(BSPF::clampw(int(myAdjustSetting) + direction, + int(AdjustSetting::START_AV_ADJ), int(AdjustSetting::END_AV_ADJ))); + // skip currently non-relevant adjustments + repeat = (myAdjustSetting == AdjustSetting::OVERSCAN && !isFullScreen) + #ifdef ADAPTABLE_REFRESH_SUPPORT + || (myAdjustSetting == AdjustSetting::ADAPT_REFRESH && !isFullScreen) + #endif + || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette) + || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS + && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING + && !isCustomFilter); + break; + + case AdjustGroup::DEBUG: + myAdjustSetting = + AdjustSetting(BSPF::clampw(int(myAdjustSetting) + direction, + int(AdjustSetting::START_DEBUG_ADJ), int(AdjustSetting::END_DEBUG_ADJ))); + repeat = (myAdjustSetting == AdjustSetting::COLOR_LOSS && !isPAL); + break; + + default: + break; + } // avoid endless loop if(repeat && !direction) direction = 1; @@ -381,6 +408,7 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) // - This array MUST have the same order as AdjustSetting const AdjustFunction ADJUST_FUNCTIONS[int(AdjustSetting::NUM_ADJ)] = { + // Audio & Video settings std::bind(&Sound::adjustVolume, &myOSystem.sound(), _1), std::bind(&FrameBuffer::selectVidMode, &myOSystem.frameBuffer(), _1), std::bind(&FrameBuffer::toggleFullscreen, &myOSystem.frameBuffer(), _1), @@ -424,6 +452,25 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&StateManager::changeState, &myOSystem.state(), _1), std::bind(&PaletteHandler::changeCurrentAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1), std::bind(&TIASurface::changeCurrentNTSCAdjustable, &myOSystem.frameBuffer().tiaSurface(), _1), + // Debug settings + std::bind(&FrameBuffer::toggleFrameStats, &myOSystem.frameBuffer(), _1), + std::bind(&Console::toggleP0Bit, &myOSystem.console(), _1), + std::bind(&Console::toggleP1Bit, &myOSystem.console(), _1), + std::bind(&Console::toggleM0Bit, &myOSystem.console(), _1), + std::bind(&Console::toggleM1Bit, &myOSystem.console(), _1), + std::bind(&Console::toggleBLBit, &myOSystem.console(), _1), + std::bind(&Console::togglePFBit, &myOSystem.console(), _1), + std::bind(&Console::toggleBits, &myOSystem.console(), _1), + std::bind(&Console::toggleP0Collision, &myOSystem.console(), _1), + std::bind(&Console::toggleP1Collision, &myOSystem.console(), _1), + std::bind(&Console::toggleM0Collision, &myOSystem.console(), _1), + std::bind(&Console::toggleM1Collision, &myOSystem.console(), _1), + std::bind(&Console::toggleBLCollision, &myOSystem.console(), _1), + std::bind(&Console::togglePFCollision, &myOSystem.console(), _1), + std::bind(&Console::toggleCollisions, &myOSystem.console(), _1), + std::bind(&Console::toggleFixedColors, &myOSystem.console(), _1), + std::bind(&Console::toggleColorLoss, &myOSystem.console(), _1), + std::bind(&Console::toggleJitter, &myOSystem.console(), _1), }; return ADJUST_FUNCTIONS[int(setting)]; @@ -446,8 +493,10 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myAdjustActive = false; myAdjustDirect = AdjustSetting::NONE; } + const bool adjustActive = myAdjustActive; - const AdjustSetting adjustDirect = myAdjustDirect; + const AdjustSetting adjustAVDirect = myAdjustDirect; + if(pressed) { myAdjustActive = false; @@ -457,6 +506,36 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) switch(event) { //////////////////////////////////////////////////////////////////////// + // Allow adjusting several (mostly repeated) settings using the same four hotkeys + case Event::PreviousSettingGroup: + case Event::NextSettingGroup: + if (pressed && !repeated) + { + const int direction = event == Event::PreviousSettingGroup ? -1 : +1; + AdjustGroup adjustGroup = AdjustGroup(BSPF::clampw(int(getAdjustGroup()) + direction, + 0, int(AdjustGroup::NUM_GROUPS) - 1)); + string msg; + + switch (adjustGroup) + { + case AdjustGroup::AV: + msg = "Audio & Video"; + myAdjustSetting = AdjustSetting::START_AV_ADJ; + break; + + case AdjustGroup::DEBUG: + msg = "Debug"; + myAdjustSetting = AdjustSetting::START_DEBUG_ADJ; + break; + + default: + break; + } + myOSystem.frameBuffer().showMessage(msg + " settings"); + myAdjustActive = false; + } + break; + // Allow adjusting several (mostly repeated) settings using the same four hotkeys case Event::PreviousSetting: case Event::NextSetting: @@ -481,9 +560,9 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) const int direction = event == Event::SettingDecrease ? -1 : +1; // if a "direct only" hotkey was pressed last, use this one - if(adjustDirect != AdjustSetting::NONE) + if(adjustAVDirect != AdjustSetting::NONE) { - myAdjustDirect = adjustDirect; + myAdjustDirect = adjustAVDirect; getAdjustSetting(myAdjustDirect)(direction); } else @@ -853,7 +932,12 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::ToggleColorLoss: - if (pressed && !repeated) myOSystem.console().toggleColorLoss(); + if (pressed && !repeated) + { + myOSystem.console().toggleColorLoss(); + myAdjustSetting = AdjustSetting::COLOR_LOSS; + myAdjustActive = true; + } return; case Event::PaletteDecrease: @@ -888,11 +972,21 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::ToggleJitter: - if (pressed && !repeated) myOSystem.console().toggleJitter(); + if (pressed && !repeated) + { + myOSystem.console().toggleJitter(); + myAdjustSetting = AdjustSetting::JITTER; + myAdjustActive = true; + } return; case Event::ToggleFrameStats: - if (pressed) myOSystem.frameBuffer().toggleFrameStats(); + if (pressed && !repeated) + { + myOSystem.frameBuffer().toggleFrameStats(); + myAdjustSetting = AdjustSetting::STATS; + myAdjustActive = true; + } return; case Event::ToggleTimeMachine: @@ -941,63 +1035,138 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::ToggleP0Collision: - if (pressed && !repeated) myOSystem.console().toggleP0Collision(); + if (pressed && !repeated) + { + myOSystem.console().toggleP0Collision(); + myAdjustSetting = AdjustSetting::P0_CX; + myAdjustActive = true; + } return; case Event::ToggleP0Bit: - if (pressed && !repeated) myOSystem.console().toggleP0Bit(); + if (pressed && !repeated) + { + myOSystem.console().toggleP0Bit(); + myAdjustSetting = AdjustSetting::P0_ENAM; + myAdjustActive = true; + } return; case Event::ToggleP1Collision: - if (pressed && !repeated) myOSystem.console().toggleP1Collision(); + if (pressed && !repeated) + { + myOSystem.console().toggleP1Collision(); + myAdjustSetting = AdjustSetting::P1_CX; + myAdjustActive = true; + } return; case Event::ToggleP1Bit: - if (pressed && !repeated) myOSystem.console().toggleP1Bit(); + if (pressed && !repeated) + { + myOSystem.console().toggleP1Bit(); + myAdjustSetting = AdjustSetting::P1_ENAM; + myAdjustActive = true; + } return; case Event::ToggleM0Collision: - if (pressed && !repeated) myOSystem.console().toggleM0Collision(); + if (pressed && !repeated) + { + myOSystem.console().toggleM0Collision(); + myAdjustSetting = AdjustSetting::M0_CX; + myAdjustActive = true; + } return; case Event::ToggleM0Bit: - if (pressed && !repeated) myOSystem.console().toggleM0Bit(); + if (pressed && !repeated) + { + myOSystem.console().toggleM0Bit(); + myAdjustSetting = AdjustSetting::M0_ENAM; + myAdjustActive = true; + } return; case Event::ToggleM1Collision: - if (pressed && !repeated) myOSystem.console().toggleM1Collision(); + if (pressed && !repeated) + { + myOSystem.console().toggleM1Collision(); + myAdjustSetting = AdjustSetting::M1_CX; + myAdjustActive = true; + } return; case Event::ToggleM1Bit: - if (pressed && !repeated) myOSystem.console().toggleM1Bit(); + if (pressed && !repeated) + { + myOSystem.console().toggleM1Bit(); + myAdjustSetting = AdjustSetting::M1_ENAM; + myAdjustActive = true; + } return; case Event::ToggleBLCollision: - if (pressed && !repeated) myOSystem.console().toggleBLCollision(); + if (pressed && !repeated) + { + myOSystem.console().toggleBLCollision(); + myAdjustSetting = AdjustSetting::BL_CX; + myAdjustActive = true; + } return; case Event::ToggleBLBit: - if (pressed) myOSystem.console().toggleBLBit(); + if (pressed && !repeated) + { + myOSystem.console().toggleBLBit(); + myAdjustSetting = AdjustSetting::BL_ENAM; + myAdjustActive = true; + } return; case Event::TogglePFCollision: - if (pressed && !repeated) myOSystem.console().togglePFCollision(); + if (pressed && !repeated) + { + myOSystem.console().togglePFCollision(); + myAdjustSetting = AdjustSetting::PF_CX; + myAdjustActive = true; + } return; case Event::TogglePFBit: - if (pressed && !repeated) myOSystem.console().togglePFBit(); - return; - - case Event::ToggleFixedColors: - if (pressed) myOSystem.console().toggleFixedColors(); + if (pressed && !repeated) + { + myOSystem.console().togglePFBit(); + myAdjustSetting = AdjustSetting::PF_ENAM; + myAdjustActive = true; + } return; case Event::ToggleCollisions: - if (pressed && !repeated) myOSystem.console().toggleCollisions(); + if (pressed && !repeated) + { + myOSystem.console().toggleCollisions(); + myAdjustSetting = AdjustSetting::ALL_CX; + myAdjustActive = true; + } return; case Event::ToggleBits: - if (pressed && !repeated) myOSystem.console().toggleBits(); + if (pressed && !repeated) + { + myOSystem.console().toggleBits(); + myAdjustSetting = AdjustSetting::ALL_ENAM; + myAdjustActive = true; + } + return; + + case Event::ToggleFixedColors: + if (pressed && !repeated) + { + myOSystem.console().toggleFixedColors(); + myAdjustSetting = AdjustSetting::FIXED_COL; + myAdjustActive = true; + } return; case Event::SaveState: @@ -2316,6 +2485,8 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::ScanlinesDecrease, "Decrease scanlines", "" }, { Event::ScanlinesIncrease, "Increase scanlines", "" }, + { Event::PreviousSettingGroup, "Select previous setting group", "" }, + { Event::NextSettingGroup, "Select next setting group", "" }, { Event::PreviousSetting, "Select previous setting", "" }, { Event::NextSetting, "Select next setting", "" }, { Event::SettingDecrease, "Decrease current setting", "" }, @@ -2414,7 +2585,10 @@ const Event::EventSet EventHandler::MiscEvents = { // Event::MouseAxisXMove, Event::MouseAxisYMove, // Event::MouseButtonLeftValue, Event::MouseButtonRightValue, Event::HandleMouseControl, Event::ToggleGrabMouse, - Event::ToggleSAPortOrder, Event::PreviousMultiCartRom + Event::ToggleSAPortOrder, Event::PreviousMultiCartRom, + Event::PreviousSettingGroup, Event::NextSettingGroup, + Event::PreviousSetting, Event::NextSetting, + Event::SettingDecrease, Event::SettingIncrease, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2435,8 +2609,6 @@ const Event::EventSet EventHandler::AudioVideoEvents = { Event::PhosphorDecrease, Event::PhosphorIncrease, Event::TogglePhosphor, Event::ScanlinesDecrease, Event::ScanlinesIncrease, Event::ToggleInter, - Event::PreviousSetting, Event::NextSetting, - Event::SettingDecrease, Event::SettingIncrease, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 5d82e31b8..324b1fb5d 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -420,15 +420,45 @@ class EventHandler NTSC_ARTIFACTS, NTSC_FRINGING, NTSC_BLEEDING, + // Other TV effects adjustables PHOSPHOR, SCANLINES, INTERPOLATION, - MAX_ADJ = INTERPOLATION, // Only used via direct hotkeys STATE, PALETTE_CHANGE_ATTRIBUTE, NTSC_CHANGE_ATTRIBUTE, - NUM_ADJ + // Debug + STATS, + P0_ENAM, + P1_ENAM, + M0_ENAM, + M1_ENAM, + BL_ENAM, + PF_ENAM, + ALL_ENAM, + P0_CX, + P1_CX, + M0_CX, + M1_CX, + BL_CX, + PF_CX, + ALL_CX, + FIXED_COL, + COLOR_LOSS, + JITTER, + // Ranges + NUM_ADJ, + START_AV_ADJ = VOLUME, + END_AV_ADJ = INTERPOLATION, + START_DEBUG_ADJ = STATS, + END_DEBUG_ADJ = JITTER, + }; + enum class AdjustGroup + { + AV, + DEBUG, + NUM_GROUPS }; private: @@ -459,6 +489,7 @@ class EventHandler // The following two methods are used for adjusting several settings using global hotkeys // They return the function used to adjust the currenly selected setting + AdjustGroup getAdjustGroup(); AdjustFunction cycleAdjustSetting(int direction); AdjustFunction getAdjustSetting(AdjustSetting setting); @@ -470,10 +501,10 @@ class EventHandler string key; }; - // ID of the currently selected global setting - AdjustSetting myAdjustSetting{AdjustSetting::VOLUME}; // If true, the setting is visible and its value can be changed bool myAdjustActive{false}; + // ID of the currently selected global setting + AdjustSetting myAdjustSetting{AdjustSetting::START_AV_ADJ}; // ID of the currently selected direct hotkey setting (0 if none) AdjustSetting myAdjustDirect{AdjustSetting::NONE}; @@ -525,7 +556,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 157 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 159 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 6ae234fa0..2f4626968 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -634,11 +634,15 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::toggleFrameStats() +void FrameBuffer::toggleFrameStats(bool toggle) { - showFrameStats(!myStatsEnabled); + if (toggle) + showFrameStats(!myStatsEnabled); myOSystem.settings().setValue( myOSystem.settings().getBool("dev.settings") ? "dev.stats" : "plr.stats", myStatsEnabled); + + myOSystem.frameBuffer().showMessage(string("Console info ") + + (myStatsEnabled ? "enabled" : "disabled")); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 544c8c6c1..58d61dfd3 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -171,7 +171,7 @@ class FrameBuffer /** Toggles showing or hiding framerate statistics. */ - void toggleFrameStats(); + void toggleFrameStats(bool toggle = true); /** Shows a message containing frame statistics for the current frame. diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 6d3461c4c..b3a48c335 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -1029,9 +1029,13 @@ bool TIA::toggleBit(TIABit b, uInt8 mode) mask = b; break; - default: + case 2: mask = (~mySpriteEnabledBits & b); break; + + default: + mask = (mySpriteEnabledBits & b); + break; } mySpriteEnabledBits = (mySpriteEnabledBits & ~b) | mask; @@ -1047,9 +1051,11 @@ bool TIA::toggleBit(TIABit b, uInt8 mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool TIA::toggleBits() +bool TIA::toggleBits(bool toggle) { - toggleBit(TIABit(0xFF), mySpriteEnabledBits > 0 ? 0 : 1); + toggleBit(TIABit(0xFF), toggle + ? mySpriteEnabledBits > 0 ? 0 : 1 + : mySpriteEnabledBits); return mySpriteEnabledBits; } @@ -1068,9 +1074,13 @@ bool TIA::toggleCollision(TIABit b, uInt8 mode) mask = b; break; - default: + case 2: mask = (~myCollisionsEnabledBits & b); break; + + default: + mask = (myCollisionsEnabledBits & b); + break; } myCollisionsEnabledBits = (myCollisionsEnabledBits & ~b) | mask; @@ -1086,9 +1096,11 @@ bool TIA::toggleCollision(TIABit b, uInt8 mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool TIA::toggleCollisions() +bool TIA::toggleCollisions(bool toggle) { - toggleCollision(TIABit(0xFF), myCollisionsEnabledBits > 0 ? 0 : 1); + toggleCollision(TIABit(0xFF), toggle + ? myCollisionsEnabledBits > 0 ? 0 : 1 + : myCollisionsEnabledBits); return myCollisionsEnabledBits; } @@ -1207,6 +1219,9 @@ bool TIA::toggleJitter(uInt8 mode) myEnableJitter = !myEnableJitter; break; + case 3: + break; + default: throw runtime_error("invalid argument for toggleJitter"); } diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index de3c373a4..3b2cbea7c 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -356,23 +356,25 @@ class TIA : public Device disabling a graphical object also disables its collisions. @param mode 1/0 indicates on/off, and values greater than 1 mean - flip the bit from its current state + 2 means flip the bit from its current state + and values greater than 2 mean return current state @return Whether the bit was enabled or disabled */ bool toggleBit(TIABit b, uInt8 mode = 2); - bool toggleBits(); + bool toggleBits(bool toggle = true); /** Enables/disable/toggle the specified (or all) TIA bit collision(s). - @param mode 1/0 indicates on/off, and values greater than 1 mean - flip the collision from its current state + @param mode 1/0 indicates on/off, + 2 means flip the collision from its current state + and values greater than 2 mean return current state @return Whether the collision was enabled or disabled */ bool toggleCollision(TIABit b, uInt8 mode = 2); - bool toggleCollisions(); + bool toggleCollisions(bool toggle = true); /** Enables/disable/toggle/query 'fixed debug colors' mode. From 279b68cb84cee9875a3334075069ebe8ed2b6479 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 3 Jul 2020 18:17:11 +0200 Subject: [PATCH 103/104] reordered and grouped event handling --- src/emucore/EventHandler.cxx | 420 ++++++++++++++++++----------------- src/emucore/EventHandler.hxx | 13 +- 2 files changed, 222 insertions(+), 211 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 53b1eee7a..536b33e65 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -448,10 +448,6 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&Console::changePhosphor, &myOSystem.console(), _1), std::bind(&TIASurface::setScanlineIntensity, &myOSystem.frameBuffer().tiaSurface(), _1), std::bind(&Console::toggleInter, &myOSystem.console(), _1), - // Following functions are not used when cycling settings but for "direct only" hotkeys - std::bind(&StateManager::changeState, &myOSystem.state(), _1), - std::bind(&PaletteHandler::changeCurrentAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1), - std::bind(&TIASurface::changeCurrentNTSCAdjustable, &myOSystem.frameBuffer().tiaSurface(), _1), // Debug settings std::bind(&FrameBuffer::toggleFrameStats, &myOSystem.frameBuffer(), _1), std::bind(&Console::toggleP0Bit, &myOSystem.console(), _1), @@ -471,6 +467,10 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&Console::toggleFixedColors, &myOSystem.console(), _1), std::bind(&Console::toggleColorLoss, &myOSystem.console(), _1), std::bind(&Console::toggleJitter, &myOSystem.console(), _1), + // Following functions are not used when cycling settings but for "direct only" hotkeys + std::bind(&StateManager::changeState, &myOSystem.state(), _1), + std::bind(&PaletteHandler::changeCurrentAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1), + std::bind(&TIASurface::changeCurrentNTSCAdjustable, &myOSystem.frameBuffer().tiaSurface(), _1), }; return ADJUST_FUNCTIONS[int(setting)]; @@ -616,20 +616,9 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) if(!myAllowAllDirectionsFlag && pressed) myEvent.set(Event::JoystickOneLeft, 0); break; - //////////////////////////////////////////////////////////////////////// - - case Event::Fry: - if(!repeated) myFryingFlag = pressed; - return; - - case Event::ReloadConsole: - if(pressed && !repeated) myOSystem.reloadConsole(true); - return; - - case Event::PreviousMultiCartRom: - if(pressed && !repeated) myOSystem.reloadConsole(false); - return; + /////////////////////////////////////////////////////////////////////////// + // Audio & Video events (with global hotkeys) case Event::VolumeDecrease: if(pressed) { @@ -675,6 +664,62 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; + case Event::ToggleFullScreen: + if (pressed && !repeated) + { + myOSystem.frameBuffer().toggleFullscreen(); + myAdjustSetting = AdjustSetting::FULLSCREEN; + myAdjustActive = true; + } + return; + + #ifdef ADAPTABLE_REFRESH_SUPPORT + case Event::ToggleAdaptRefresh: + if (pressed && !repeated) + { + myOSystem.frameBuffer().toggleAdaptRefresh(); + myAdjustSetting = AdjustSetting::ADAPT_REFRESH; + myAdjustActive = true; + } + return; + #endif + + case Event::OverscanDecrease: + if (pressed) + { + myOSystem.frameBuffer().changeOverscan(-1); + myAdjustSetting = AdjustSetting::OVERSCAN; + myAdjustActive = true; + } + return; + + case Event::OverscanIncrease: + if (pressed) + { + myOSystem.frameBuffer().changeOverscan(+1); + myAdjustSetting = AdjustSetting::OVERSCAN; + myAdjustActive = true; + } + return; + + case Event::FormatDecrease: + if (pressed && !repeated) + { + myOSystem.console().selectFormat(-1); + myAdjustSetting = AdjustSetting::TVFORMAT; + myAdjustActive = true; + } + return; + + case Event::FormatIncrease: + if (pressed && !repeated) + { + myOSystem.console().selectFormat(+1); + myAdjustSetting = AdjustSetting::TVFORMAT; + myAdjustActive = true; + } + return; + case Event::VCenterDecrease: if(pressed) { @@ -711,72 +756,20 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; - case Event::PreviousPaletteAttribute: - if(pressed) + case Event::PaletteDecrease: + if (pressed && !repeated) { - myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(-1); - myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; - } - return; - - case Event::NextPaletteAttribute: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(+1); - myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; - } - return; - - case Event::PaletteAttributeDecrease: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().paletteHandler().changeCurrentAdjustable(-1); - myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; - } - return; - - case Event::PaletteAttributeIncrease: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().paletteHandler().changeCurrentAdjustable(+1); - myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; - } - return; - - case Event::ToggleFullScreen: - if(pressed && !repeated) - { - myOSystem.frameBuffer().toggleFullscreen(); - myAdjustSetting = AdjustSetting::FULLSCREEN; + myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(-1); + myAdjustSetting = AdjustSetting::PALETTE; myAdjustActive = true; } return; - #ifdef ADAPTABLE_REFRESH_SUPPORT - case Event::ToggleAdaptRefresh: - if(pressed && !repeated) + case Event::PaletteIncrease: + if (pressed && !repeated) { - myOSystem.frameBuffer().toggleAdaptRefresh(); - myAdjustSetting = AdjustSetting::ADAPT_REFRESH; - myAdjustActive = true; - } - return; - #endif - - case Event::OverscanDecrease: - if(pressed) - { - myOSystem.frameBuffer().changeOverscan(-1); - myAdjustSetting = AdjustSetting::OVERSCAN; - myAdjustActive = true; - } - return; - - case Event::OverscanIncrease: - if(pressed) - { - myOSystem.frameBuffer().changeOverscan(+1); - myAdjustSetting = AdjustSetting::OVERSCAN; + myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(+1); + myAdjustSetting = AdjustSetting::PALETTE; myAdjustActive = true; } return; @@ -852,58 +845,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myAdjustActive = true; } return; - - case Event::PreviousAttribute: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().setNTSCAdjustable(-1); - myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; - } - return; - - case Event::NextAttribute: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().setNTSCAdjustable(+1); - myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; - } - return; - - case Event::DecreaseAttribute: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().changeCurrentNTSCAdjustable(-1); - myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; - } - return; - - case Event::IncreaseAttribute: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().changeCurrentNTSCAdjustable(+1); - myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; - } - return; - - case Event::ScanlinesDecrease: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(-1); - myAdjustSetting = AdjustSetting::SCANLINES; - myAdjustActive = true; - - } - return; - - case Event::ScanlinesIncrease: - if(pressed) - { - myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(+1); - myAdjustSetting = AdjustSetting::SCANLINES; - myAdjustActive = true; - } - return; - case Event::PhosphorDecrease: if(pressed) { @@ -931,29 +872,20 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; - case Event::ToggleColorLoss: - if (pressed && !repeated) + case Event::ScanlinesDecrease: + if (pressed) { - myOSystem.console().toggleColorLoss(); - myAdjustSetting = AdjustSetting::COLOR_LOSS; + myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(-1); + myAdjustSetting = AdjustSetting::SCANLINES; myAdjustActive = true; } return; - case Event::PaletteDecrease: - if(pressed && !repeated) + case Event::ScanlinesIncrease: + if (pressed) { - myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(-1); - myAdjustSetting = AdjustSetting::PALETTE; - myAdjustActive = true; - } - return; - - case Event::PaletteIncrease: - if(pressed && !repeated) - { - myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(+1); - myAdjustSetting = AdjustSetting::PALETTE; + myOSystem.frameBuffer().tiaSurface().setScanlineIntensity(+1); + myAdjustSetting = AdjustSetting::SCANLINES; myAdjustActive = true; } return; @@ -967,19 +899,75 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; - case Event::ToggleTurbo: - if (pressed && !repeated) myOSystem.console().toggleTurbo(); - return; - - case Event::ToggleJitter: - if (pressed && !repeated) + /////////////////////////////////////////////////////////////////////////// + // Direct key Audio & Video events + case Event::PreviousPaletteAttribute: + if (pressed) { - myOSystem.console().toggleJitter(); - myAdjustSetting = AdjustSetting::JITTER; - myAdjustActive = true; + myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(-1); + myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; } return; + case Event::NextPaletteAttribute: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(+1); + myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; + } + return; + + case Event::PaletteAttributeDecrease: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().paletteHandler().changeCurrentAdjustable(-1); + myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; + } + return; + + case Event::PaletteAttributeIncrease: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().paletteHandler().changeCurrentAdjustable(+1); + myAdjustDirect = AdjustSetting::PALETTE_CHANGE_ATTRIBUTE; + } + return; + + case Event::PreviousAttribute: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().setNTSCAdjustable(-1); + myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; + } + return; + + case Event::NextAttribute: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().setNTSCAdjustable(+1); + myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; + } + return; + + case Event::DecreaseAttribute: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().changeCurrentNTSCAdjustable(-1); + myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; + } + return; + + case Event::IncreaseAttribute: + if (pressed) + { + myOSystem.frameBuffer().tiaSurface().changeCurrentNTSCAdjustable(+1); + myAdjustDirect = AdjustSetting::NTSC_CHANGE_ATTRIBUTE; + } + return; + + /////////////////////////////////////////////////////////////////////////// + // Debug events (with global hotkeys) + case Event::ToggleFrameStats: if (pressed && !repeated) { @@ -989,51 +977,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; - case Event::ToggleTimeMachine: - if (pressed && !repeated) myOSystem.state().toggleTimeMachine(); - return; - - #ifdef PNG_SUPPORT - case Event::ToggleContSnapshots: - if (pressed && !repeated) myOSystem.png().toggleContinuousSnapshots(false); - return; - - case Event::ToggleContSnapshotsFrame: - if (pressed && !repeated) myOSystem.png().toggleContinuousSnapshots(true); - return; - #endif - - case Event::HandleMouseControl: - if (pressed && !repeated) handleMouseControl(); - return; - - case Event::ToggleSAPortOrder: - if (pressed && !repeated) toggleSAPortOrder(); - return; - - case Event::FormatDecrease: - if(pressed && !repeated) - { - myOSystem.console().selectFormat(-1); - myAdjustSetting = AdjustSetting::TVFORMAT; - myAdjustActive = true; - } - return; - - case Event::FormatIncrease: - if(pressed && !repeated) - { - myOSystem.console().selectFormat(+1); - myAdjustSetting = AdjustSetting::TVFORMAT; - myAdjustActive = true; - } - return; - - case Event::ToggleGrabMouse: - if (pressed && !repeated && !myOSystem.frameBuffer().fullScreen()) - myOSystem.frameBuffer().toggleGrabMouse(); - return; - case Event::ToggleP0Collision: if (pressed && !repeated) { @@ -1169,8 +1112,29 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; + case Event::ToggleColorLoss: + if (pressed && !repeated) + { + myOSystem.console().toggleColorLoss(); + myAdjustSetting = AdjustSetting::COLOR_LOSS; + myAdjustActive = true; + } + return; + + case Event::ToggleJitter: + if (pressed && !repeated) + { + myOSystem.console().toggleJitter(); + myAdjustSetting = AdjustSetting::JITTER; + myAdjustActive = true; + } + return; + + /////////////////////////////////////////////////////////////////////////// + // State events + case Event::SaveState: - if(pressed && !repeated) + if (pressed && !repeated) { myOSystem.state().saveState(); myAdjustDirect = AdjustSetting::STATE; @@ -1183,7 +1147,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::PreviousState: - if(pressed) + if (pressed) { myOSystem.state().changeState(-1); myAdjustDirect = AdjustSetting::STATE; @@ -1191,7 +1155,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::NextState: - if(pressed) + if (pressed) { myOSystem.state().changeState(+1); myAdjustDirect = AdjustSetting::STATE; @@ -1203,7 +1167,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; case Event::LoadState: - if(pressed && !repeated) + if (pressed && !repeated) { myOSystem.state().loadState(); myAdjustDirect = AdjustSetting::STATE; @@ -1251,6 +1215,52 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) if (pressed) enterTimeMachineMenuMode(1000, true); return; + /////////////////////////////////////////////////////////////////////////// + // Misc events + + case Event::ToggleTurbo: + if (pressed && !repeated) myOSystem.console().toggleTurbo(); + return; + + case Event::Fry: + if (!repeated) myFryingFlag = pressed; + return; + + case Event::ReloadConsole: + if (pressed && !repeated) myOSystem.reloadConsole(true); + return; + + case Event::PreviousMultiCartRom: + if (pressed && !repeated) myOSystem.reloadConsole(false); + return; + + case Event::ToggleTimeMachine: + if (pressed && !repeated) myOSystem.state().toggleTimeMachine(); + return; + + #ifdef PNG_SUPPORT + case Event::ToggleContSnapshots: + if (pressed && !repeated) myOSystem.png().toggleContinuousSnapshots(false); + return; + + case Event::ToggleContSnapshotsFrame: + if (pressed && !repeated) myOSystem.png().toggleContinuousSnapshots(true); + return; + #endif + + case Event::HandleMouseControl: + if (pressed && !repeated) handleMouseControl(); + return; + + case Event::ToggleSAPortOrder: + if (pressed && !repeated) toggleSAPortOrder(); + return; + + case Event::ToggleGrabMouse: + if (pressed && !repeated && !myOSystem.frameBuffer().fullScreen()) + myOSystem.frameBuffer().toggleGrabMouse(); + return; + case Event::TakeSnapshot: if(pressed && !repeated) myOSystem.frameBuffer().tiaSurface().saveSnapShot(); return; @@ -1363,7 +1373,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) if(myComboTable[combo][i] != Event::NoType) handleEvent(myComboTable[combo][i], pressed, repeated); return; - //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Events which relate to switches() @@ -1488,6 +1497,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myOSystem.console().switches().update(); } return; + //////////////////////////////////////////////////////////////////////// case Event::NoType: // Ignore unmapped events diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 324b1fb5d..0ff428998 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -395,6 +395,7 @@ class EventHandler enum class AdjustSetting { NONE = -1, + // *** Audio & Video group *** VOLUME, ZOOM, FULLSCREEN, @@ -424,11 +425,7 @@ class EventHandler PHOSPHOR, SCANLINES, INTERPOLATION, - // Only used via direct hotkeys - STATE, - PALETTE_CHANGE_ATTRIBUTE, - NTSC_CHANGE_ATTRIBUTE, - // Debug + // *** Debug group *** STATS, P0_ENAM, P1_ENAM, @@ -447,7 +444,11 @@ class EventHandler FIXED_COL, COLOR_LOSS, JITTER, - // Ranges + // *** Only used via direct hotkeys *** + STATE, + PALETTE_CHANGE_ATTRIBUTE, + NTSC_CHANGE_ATTRIBUTE, + // *** Ranges *** NUM_ADJ, START_AV_ADJ = VOLUME, END_AV_ADJ = INTERPOLATION, From f6f7f064b1fe108400b2e8de5fd08ae19d9cd5b6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 3 Jul 2020 14:46:57 -0230 Subject: [PATCH 104/104] Moved 'max ROM size' function to more appropriate place. --- src/common/bspf.hxx | 3 --- src/emucore/Cart.hxx | 3 +++ src/emucore/FSNode.cxx | 5 +++-- src/libretro/FSNodeLIBRETRO.cxx | 3 ++- src/libretro/StellaLIBRETRO.hxx | 3 ++- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index a887bf80a..5201ef2ff 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -128,9 +128,6 @@ namespace BSPF static const string ARCH = "NOARCH"; #endif - // Maximum size of a ROM that Stella can support - inline constexpr size_t romMaxSize() { return 512_KB; } - // Get next power of two greater than or equal to the given value inline size_t nextPowerOfTwo(size_t size) { if(size < 2) return 1; diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 8ccd10d79..8a2e4656e 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -48,6 +48,9 @@ class Cartridge : public Device public: using StartBankFromPropsFunc = std::function; + // Maximum size of a ROM cart that Stella can support + static constexpr size_t maxSize() { return 512_KB; } + public: /** Create a new cartridge diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 0d9e53ad1..e9da05b03 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -18,6 +18,7 @@ // Copyright (C) 2002-2004 The ScummVM project //============================================================================ +#include "Cart.hxx" #include "FSNodeFactory.hxx" #include "FSNode.hxx" @@ -237,7 +238,7 @@ size_t FilesystemNode::read(ByteBuffer& image) const return size; // Otherwise, the default behaviour is to read from a normal C++ ifstream - image = make_unique(BSPF::romMaxSize()); + image = make_unique(Cartridge::maxSize()); ifstream in(getPath(), std::ios::binary); if (in) { @@ -248,7 +249,7 @@ size_t FilesystemNode::read(ByteBuffer& image) const if (length == 0) throw runtime_error("Zero-byte file"); - size = std::min(length, BSPF::romMaxSize()); + size = std::min(length, Cartridge::maxSize()); in.read(reinterpret_cast(image.get()), size); } else diff --git a/src/libretro/FSNodeLIBRETRO.cxx b/src/libretro/FSNodeLIBRETRO.cxx index 8c242391b..f3670f0a2 100644 --- a/src/libretro/FSNodeLIBRETRO.cxx +++ b/src/libretro/FSNodeLIBRETRO.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "bspf.hxx" +#include "Cart.hxx" #include "FSNodeLIBRETRO.hxx" #ifdef _WIN32 @@ -93,7 +94,7 @@ AbstractFSNodePtr FilesystemNodeLIBRETRO::getParent() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - size_t FilesystemNodeLIBRETRO::read(ByteBuffer& image) const { - image = make_unique(BSPF::romMaxSize()); + image = make_unique(Cartridge::maxSize()); extern uInt32 libretro_read_rom(void* data); return libretro_read_rom(image.get()); diff --git a/src/libretro/StellaLIBRETRO.hxx b/src/libretro/StellaLIBRETRO.hxx index 01c2cbaf7..b3d87725b 100644 --- a/src/libretro/StellaLIBRETRO.hxx +++ b/src/libretro/StellaLIBRETRO.hxx @@ -21,6 +21,7 @@ #include "bspf.hxx" #include "OSystemLIBRETRO.hxx" +#include "Cart.hxx" #include "Console.hxx" #include "ConsoleTiming.hxx" #include "Control.hxx" @@ -59,7 +60,7 @@ class StellaLIBRETRO void* getROM() const { return rom_image.get(); } uInt32 getROMSize() const { return rom_size; } - constexpr uInt32 getROMMax() const { return BSPF::romMaxSize(); } + constexpr uInt32 getROMMax() const { return Cartridge::maxSize(); } uInt8* getRAM() { return system_ram; } constexpr uInt32 getRAMSize() const { return 128; }