From 73fdbf893faeb0ec033729d82cddf1f1904b5419 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 28 Sep 2010 21:25:29 +1000 Subject: [PATCH] Update to v070r02 release. byuu says: - added NTSC/PAL TV output mode selection - added loading support for BSX Slotted, BSX, Sufami Turbo and Super Game Boy games --- bsnes/snes/snes.hpp | 2 +- bsnes/ui-phoenix/base.hpp | 6 + bsnes/ui-phoenix/cartridge/cartridge.cpp | 67 +++++++++- bsnes/ui-phoenix/cartridge/cartridge.hpp | 6 +- bsnes/ui-phoenix/config.cpp | 4 + bsnes/ui-phoenix/config.hpp | 4 + bsnes/ui-phoenix/general/file-browser.cpp | 53 ++++++-- bsnes/ui-phoenix/general/file-browser.hpp | 5 +- bsnes/ui-phoenix/general/general.cpp | 1 + bsnes/ui-phoenix/general/general.hpp | 1 + bsnes/ui-phoenix/general/main-window.cpp | 27 +++- bsnes/ui-phoenix/general/main-window.hpp | 10 +- bsnes/ui-phoenix/general/slot-loader.cpp | 147 ++++++++++++++++++++++ bsnes/ui-phoenix/general/slot-loader.hpp | 38 ++++++ bsnes/ui-phoenix/interface.cpp | 14 +++ bsnes/ui-phoenix/main.cpp | 5 +- bsnes/ui-phoenix/utility/utility.cpp | 24 ++-- bsnes/ui-phoenix/utility/utility.hpp | 3 +- 18 files changed, 381 insertions(+), 36 deletions(-) create mode 100755 bsnes/ui-phoenix/general/slot-loader.cpp create mode 100755 bsnes/ui-phoenix/general/slot-loader.hpp diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index e2599734..1d952b10 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "070.01"; + static const char Version[] = "070.02"; static const unsigned SerializerVersion = 13; } } diff --git a/bsnes/ui-phoenix/base.hpp b/bsnes/ui-phoenix/base.hpp index 3fe992c0..2385b143 100755 --- a/bsnes/ui-phoenix/base.hpp +++ b/bsnes/ui-phoenix/base.hpp @@ -38,23 +38,29 @@ extern Application application; struct Style { enum : unsigned { #if defined(PHOENIX_WINDOWS) + ButtonHeight = 25, CheckBoxHeight = 15, ComboBoxHeight = 22, EditBoxHeight = 22, LabelHeight = 15, SliderHeight = 25, + TextBoxHeight = 22, #elif defined(PHOENIX_GTK) + ButtonHeight = 25, CheckBoxHeight = 15, ComboBoxHeight = 22, EditBoxHeight = 22, LabelHeight = 15, SliderHeight = 22, + TextBoxHeight = 22, #elif defined(PHOENIX_QT) + ButtonHeight = 25, CheckBoxHeight = 15, ComboBoxHeight = 22, EditBoxHeight = 22, LabelHeight = 15, SliderHeight = 22, + TextBoxHeight = 22, #endif }; }; diff --git a/bsnes/ui-phoenix/cartridge/cartridge.cpp b/bsnes/ui-phoenix/cartridge/cartridge.cpp index d0830193..39b88d24 100755 --- a/bsnes/ui-phoenix/cartridge/cartridge.cpp +++ b/bsnes/ui-phoenix/cartridge/cartridge.cpp @@ -1,10 +1,10 @@ #include "../base.hpp" Cartridge cartridge; -bool Cartridge::loadNormal(const char *filename) { +bool Cartridge::loadNormal(const char *basename) { unload(); - if(loadCartridge(SNES::memory::cartrom, baseXML, filename) == false) return false; - baseName = nall::basename(filename); + if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + baseName = nall::basename(basename); SNES::cartridge.load(SNES::Cartridge::Mode::Normal, lstring() << baseXML); loadMemory(SNES::memory::cartram, baseName, ".srm"); loadMemory(SNES::memory::cartrtc, baseName, ".rtc"); @@ -12,10 +12,71 @@ bool Cartridge::loadNormal(const char *filename) { return true; } +bool Cartridge::loadBsxSlotted(const char *basename, const char *slotname) { + unload(); + if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + loadCartridge(SNES::memory::bsxflash, slotAXML, slotname); + baseName = nall::basename(basename); + slotAName = nall::basename(slotname); + SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted, lstring() << baseXML << slotAXML); + loadMemory(SNES::memory::cartram, baseName, ".srm"); + loadMemory(SNES::memory::cartrtc, baseName, ".rtc"); + utility.cartridgeLoaded(); + return true; +} + +bool Cartridge::loadBsx(const char *basename, const char *slotname) { + unload(); + if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + loadCartridge(SNES::memory::bsxflash, slotAXML, slotname); + baseName = nall::basename(basename); + slotAName = nall::basename(slotname); + SNES::cartridge.load(SNES::Cartridge::Mode::Bsx, lstring() << baseXML << slotAXML); + loadMemory(SNES::memory::bsxram, baseName, ".srm"); + loadMemory(SNES::memory::bsxpram, baseName, ".psr"); + utility.cartridgeLoaded(); + return true; +} + +bool Cartridge::loadSufamiTurbo(const char *basename, const char *slotAname, const char *slotBname) { + unload(); + if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + loadCartridge(SNES::memory::stArom, slotAXML, slotAname); + loadCartridge(SNES::memory::stBrom, slotBXML, slotBname); + baseName = nall::basename(basename); + slotAName = nall::basename(slotAname); + slotBName = nall::basename(slotBname); + SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo, lstring() << baseXML << slotAXML << slotBXML); + loadMemory(SNES::memory::stAram, slotAName, ".srm"); + loadMemory(SNES::memory::stBram, slotBName, ".srm"); + utility.cartridgeLoaded(); + return true; +} + +bool Cartridge::loadSuperGameBoy(const char *basename, const char *slotname) { + unload(); + if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + loadCartridge(SNES::memory::gbrom, slotAXML, slotname); + baseName = nall::basename(basename); + slotAName = nall::basename(slotname); + SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, lstring() << baseXML << slotAXML); + loadMemory(SNES::memory::gbram, slotAName, ".sav"); + loadMemory(SNES::memory::gbrtc, slotAName, ".rtc"); + utility.cartridgeLoaded(); + return true; +} + void Cartridge::unload() { if(SNES::cartridge.loaded() == false) return; saveMemory(SNES::memory::cartram, baseName, ".srm"); saveMemory(SNES::memory::cartrtc, baseName, ".rtc"); + saveMemory(SNES::memory::bsxram, baseName, ".srm"); + saveMemory(SNES::memory::bsxpram, baseName, ".psr"); + saveMemory(SNES::memory::stAram, slotAName, ".srm"); + saveMemory(SNES::memory::stBram, slotBName, ".srm"); + saveMemory(SNES::memory::gbram, slotAName, ".sav"); + saveMemory(SNES::memory::gbrtc, slotAName, ".rtc"); + baseName = slotAName = slotBName = ""; utility.cartridgeUnloaded(); } diff --git a/bsnes/ui-phoenix/cartridge/cartridge.hpp b/bsnes/ui-phoenix/cartridge/cartridge.hpp index fccd350b..91b9e370 100755 --- a/bsnes/ui-phoenix/cartridge/cartridge.hpp +++ b/bsnes/ui-phoenix/cartridge/cartridge.hpp @@ -1,5 +1,9 @@ struct Cartridge { - bool loadNormal(const char *filename); + bool loadNormal(const char *basename); + bool loadBsxSlotted(const char *basename, const char *slotname); + bool loadBsx(const char *basename, const char *slotname); + bool loadSufamiTurbo(const char *basename, const char *slotAname, const char *slotBname); + bool loadSuperGameBoy(const char *basename, const char *slotname); void unload(); string baseName, slotAName, slotBName; diff --git a/bsnes/ui-phoenix/config.cpp b/bsnes/ui-phoenix/config.cpp index 17ffd8e5..983a8ff1 100755 --- a/bsnes/ui-phoenix/config.cpp +++ b/bsnes/ui-phoenix/config.cpp @@ -11,9 +11,13 @@ void Configuration::save() { void Configuration::create() { attach(path.current = "", "path.current"); + attach(path.satellaviewBios = "", "path.satellaviewBios"); + attach(path.sufamiTurboBios = "", "path.sufamiTurboBios"); + attach(path.superGameBoyBios = "", "path.superGameBoyBios"); attach(video.driver = "", "video.driver"); attach(video.synchronize = false, "video.synchronize"); + attach(video.region = 0, "video.region"); attach(video.smooth = true, "video.smooth"); attach(video.scale = 2, "video.scale"); attach(video.aspectRatioCorrection = true, "video.aspectRatioCorrection"); diff --git a/bsnes/ui-phoenix/config.hpp b/bsnes/ui-phoenix/config.hpp index 92dba0f0..d1f65372 100755 --- a/bsnes/ui-phoenix/config.hpp +++ b/bsnes/ui-phoenix/config.hpp @@ -3,11 +3,15 @@ struct Configuration : public configuration { string base; string user; string current; + string satellaviewBios; + string sufamiTurboBios; + string superGameBoyBios; } path; struct Video { string driver; bool synchronize; + bool region; bool smooth; unsigned scale; bool aspectRatioCorrection; diff --git a/bsnes/ui-phoenix/general/file-browser.cpp b/bsnes/ui-phoenix/general/file-browser.cpp index dc7d71f5..26a5eda3 100755 --- a/bsnes/ui-phoenix/general/file-browser.cpp +++ b/bsnes/ui-phoenix/general/file-browser.cpp @@ -5,9 +5,8 @@ void FileBrowser::create() { Window::create(0, 0, 256, 256, "Load Cartridge"); setDefaultFont(application.proportionalFont); - unsigned x = 5, y = 5; + unsigned x = 5, y = 5, height = Style::TextBoxHeight; - unsigned height = Style::EditBoxHeight; pathBox.create(*this, x, y, 630 - height - height - 10, height); browseButton.create(*this, x + 630 - height - height - 5, y, height, height, "..."); upButton.create(*this, x + 630 - height, y, height, height, ".."); y += height + 5; @@ -22,18 +21,42 @@ void FileBrowser::create() { contentsBox.onActivate = { &FileBrowser::fileActivate, this }; } -void FileBrowser::fileOpen(const char *pathname) { +void FileBrowser::fileOpen(FileBrowser::Mode requestedMode, function requestedCallback) { + callback = requestedCallback; + if(mode == requestedMode && string(folder, "/") == config.path.current) { + setVisible(); + contentsBox.setFocused(); + return; + } + + filters.reset(); + switch(mode = requestedMode) { + case Mode::Cartridge: { + filters.append(".sfc"); + break; + } + case Mode::Satellaview: { + filters.append(".bs"); + break; + } + case Mode::SufamiTurbo: { + filters.append(".st"); + break; + } + case Mode::GameBoy: { + filters.append(".gb"); + filters.append(".gbc"); + filters.append(".sgb"); + } + } + setVisible(false); - setFolder(pathname); + setFolder(config.path.current); setVisible(true); contentsBox.setFocused(); } void FileBrowser::setFolder(const char *pathname) { - string path = pathname; - path.rtrim("/"); - if(folder == path) return; - contentsBox.reset(); contents.reset(); @@ -43,7 +66,14 @@ void FileBrowser::setFolder(const char *pathname) { pathBox.setText(folder); lstring contentsList = directory::contents(folder); foreach(item, contentsList) { - if(strend(item, "/") || strend(item, ".sfc")) contents.append(item); + if(strend(item, "/")) { + contents.append(item); + } else foreach(filter, filters) { + if(strend(item, filter)) { + contents.append(item); + break; + } + } } foreach(item, contents) contentsBox.addItem(item); contentsBox.setSelection(0); @@ -65,9 +95,10 @@ void FileBrowser::fileActivate() { if(strend(filename, "/")) { setFolder(string(folder, "/", filename)); } else { - filename = string(folder, "/", filename); - cartridge.loadNormal(filename); setVisible(false); + filename = string(folder, "/", filename); + config.path.current = dir(filename); + if(callback) callback(filename); } } } diff --git a/bsnes/ui-phoenix/general/file-browser.hpp b/bsnes/ui-phoenix/general/file-browser.hpp index 5dd3594d..ce844f82 100755 --- a/bsnes/ui-phoenix/general/file-browser.hpp +++ b/bsnes/ui-phoenix/general/file-browser.hpp @@ -4,11 +4,14 @@ struct FileBrowser : Window { Button upButton; ListBox contentsBox; - void fileOpen(const char *pathname); + enum class Mode : unsigned { Cartridge, Satellaview, SufamiTurbo, GameBoy } mode; + void fileOpen(Mode mode, function callback); void create(); private: + function callback; string folder; + lstring filters; lstring contents; void folderBrowse(); diff --git a/bsnes/ui-phoenix/general/general.cpp b/bsnes/ui-phoenix/general/general.cpp index 1c06a519..50e7f351 100755 --- a/bsnes/ui-phoenix/general/general.cpp +++ b/bsnes/ui-phoenix/general/general.cpp @@ -1,3 +1,4 @@ #include "../base.hpp" #include "main-window.cpp" #include "file-browser.cpp" +#include "slot-loader.cpp" diff --git a/bsnes/ui-phoenix/general/general.hpp b/bsnes/ui-phoenix/general/general.hpp index 737238df..a0f43444 100755 --- a/bsnes/ui-phoenix/general/general.hpp +++ b/bsnes/ui-phoenix/general/general.hpp @@ -1,2 +1,3 @@ #include "main-window.hpp" #include "file-browser.hpp" +#include "slot-loader.hpp" diff --git a/bsnes/ui-phoenix/general/main-window.cpp b/bsnes/ui-phoenix/general/main-window.cpp index f2e99856..6d605487 100755 --- a/bsnes/ui-phoenix/general/main-window.cpp +++ b/bsnes/ui-phoenix/general/main-window.cpp @@ -9,6 +9,12 @@ void MainWindow::create() { system.create(*this, "System"); systemLoadCartridge.create(system, "Load Cartridge ..."); + systemLoadCartridgeSpecial.create(system, "Load Special"); + systemLoadCartridgeBsxSlotted.create(systemLoadCartridgeSpecial, "Load BS-X Slotted Cartridge ..."); + systemLoadCartridgeBsx.create(systemLoadCartridgeSpecial, "Load BS-X Cartridge ..."); + systemLoadCartridgeSufamiTurbo.create(systemLoadCartridgeSpecial, "Load Sufami Turbo Cartridge ..."); + systemLoadCartridgeSuperGameBoy.create(systemLoadCartridgeSpecial, "Load Super Game Boy Cartridge ..."); + systemLoadCartridgeSuperGameBoy.setEnabled(SNES::supergameboy.opened()); systemSeparator1.create(system); systemPower.create(system, "Power Cycle"); systemReset.create(system, "Reset"); @@ -30,9 +36,14 @@ void MainWindow::create() { if(config.video.scale == 3) settingsVideoMode3x.setChecked(); if(config.video.scale == 4) settingsVideoMode4x.setChecked(); if(config.video.scale == 5) settingsVideoMode5x.setChecked(); - settingsVideoModeSeparator.create(settingsVideoMode); + settingsVideoModeSeparator1.create(settingsVideoMode); settingsVideoModeAspectRatioCorrection.create(settingsVideoMode, "Correct Aspect Ratio"); settingsVideoModeAspectRatioCorrection.setChecked(config.video.aspectRatioCorrection); + settingsVideoModeSeparator2.create(settingsVideoMode); + settingsVideoModeNTSC.create(settingsVideoMode, "NTSC"); + settingsVideoModePAL.create(settingsVideoModeNTSC, "PAL"); + if(config.video.region == 0) settingsVideoModeNTSC.setChecked(); + if(config.video.region == 1) settingsVideoModePAL.setChecked(); settingsSmoothVideo.create(settings, "Smooth Video"); settingsSmoothVideo.setChecked(config.video.smooth); settingsSeparator1.create(settings); @@ -72,9 +83,11 @@ void MainWindow::create() { setMenuVisible(true); setStatusVisible(true); - systemLoadCartridge.onTick = []() { - utility.loadCartridgeNormal(); - }; + systemLoadCartridge.onTick = []() { utility.loadCartridgeNormal(); }; + systemLoadCartridgeBsxSlotted.onTick = []() { singleSlotLoader.loadCartridgeBsxSlotted(); }; + systemLoadCartridgeBsx.onTick = []() { singleSlotLoader.loadCartridgeBsx(); }; + systemLoadCartridgeSufamiTurbo.onTick = []() { doubleSlotLoader.loadCartridgeSufamiTurbo(); }; + systemLoadCartridgeSuperGameBoy.onTick = []() { singleSlotLoader.loadCartridgeSuperGameBoy(); }; systemPower.onTick = []() { SNES::system.power(); @@ -93,9 +106,13 @@ void MainWindow::create() { settingsVideoMode5x.onTick = []() { utility.setScale(5); }; settingsVideoModeAspectRatioCorrection.onTick = []() { - utility.setAspectRatioCorrection(mainWindow.settingsVideoModeAspectRatioCorrection.checked()); + config.video.aspectRatioCorrection = mainWindow.settingsVideoModeAspectRatioCorrection.checked(); + utility.setScale(); }; + settingsVideoModeNTSC.onTick = []() { config.video.region = 0; utility.setScale(); }; + settingsVideoModePAL.onTick = []() { config.video.region = 1; utility.setScale(); }; + settingsSmoothVideo.onTick = []() { config.video.smooth = mainWindow.settingsSmoothVideo.checked(); video.set(Video::Filter, (unsigned)config.video.smooth); diff --git a/bsnes/ui-phoenix/general/main-window.hpp b/bsnes/ui-phoenix/general/main-window.hpp index 3a4fd35f..eb466a3b 100755 --- a/bsnes/ui-phoenix/general/main-window.hpp +++ b/bsnes/ui-phoenix/general/main-window.hpp @@ -1,6 +1,11 @@ struct MainWindow : Window { Menu system; MenuItem systemLoadCartridge; + Menu systemLoadCartridgeSpecial; + MenuItem systemLoadCartridgeBsxSlotted; + MenuItem systemLoadCartridgeBsx; + MenuItem systemLoadCartridgeSufamiTurbo; + MenuItem systemLoadCartridgeSuperGameBoy; MenuSeparator systemSeparator1; MenuItem systemPower; MenuItem systemReset; @@ -14,8 +19,11 @@ struct MainWindow : Window { MenuRadioItem settingsVideoMode3x; MenuRadioItem settingsVideoMode4x; MenuRadioItem settingsVideoMode5x; - MenuSeparator settingsVideoModeSeparator; + MenuSeparator settingsVideoModeSeparator1; MenuCheckItem settingsVideoModeAspectRatioCorrection; + MenuSeparator settingsVideoModeSeparator2; + MenuRadioItem settingsVideoModeNTSC; + MenuRadioItem settingsVideoModePAL; MenuCheckItem settingsSmoothVideo; MenuSeparator settingsSeparator1; MenuCheckItem settingsSynchronizeVideo; diff --git a/bsnes/ui-phoenix/general/slot-loader.cpp b/bsnes/ui-phoenix/general/slot-loader.cpp new file mode 100755 index 00000000..8dbb8500 --- /dev/null +++ b/bsnes/ui-phoenix/general/slot-loader.cpp @@ -0,0 +1,147 @@ +SingleSlotLoader singleSlotLoader; +DoubleSlotLoader doubleSlotLoader; + +void SingleSlotLoader::create() { + application.windows.append(this); + Window::create(0, 0, 256, 256); + setDefaultFont(application.proportionalFont); + + unsigned x = 5, y = 5, height = Style::TextBoxHeight, width = 365 + height; + + baseLabel.create(*this, x, y, 50, height, "Base:"); + basePath.create(*this, x + 50, y, 300, height); + baseBrowse.create(*this, x + 355, y, height, height, "..."); y += height + 5; + + slotLabel.create(*this, x, y, 50, height, "Slot:"); + slotPath.create(*this, x + 50, y, 300, height); + slotBrowse.create(*this, x + 355, y, height, height, "..."); y += height + 5; + + okButton.create(*this, x + width - 85, y, 80, Style::ButtonHeight, "Ok"); y += Style::ButtonHeight + 5; + + setGeometry(160, 160, width, y); + + baseBrowse.onTick = []() { + fileBrowser.fileOpen(FileBrowser::Mode::Cartridge, [](string filename) { + singleSlotLoader.basePath.setText(filename); + }); + }; + + slotBrowse.onTick = []() { + FileBrowser::Mode fileMode = (singleSlotLoader.mode == Mode::SuperGameBoy + ? FileBrowser::Mode::GameBoy : FileBrowser::Mode::Satellaview); + fileBrowser.fileOpen(fileMode, [](string filename) { + singleSlotLoader.slotPath.setText(filename); + }); + }; + + okButton.onTick = { &SingleSlotLoader::load, this }; +} + +void SingleSlotLoader::loadCartridgeBsxSlotted() { + mode = Mode::BsxSlotted; + setTitle("Load BS-X Slotted Cartridge"); + basePath.setText(""); + slotPath.setText(""); + setVisible(); + okButton.setFocused(); +} + +void SingleSlotLoader::loadCartridgeBsx() { + mode = Mode::Bsx; + setTitle("Load BS-X Cartridge"); + basePath.setText(config.path.satellaviewBios); + slotPath.setText(""); + setVisible(); + okButton.setFocused(); +} + +void SingleSlotLoader::loadCartridgeSuperGameBoy() { + mode = Mode::SuperGameBoy; + setTitle("Load Super Game Boy cartridge"); + basePath.setText(config.path.superGameBoyBios); + slotPath.setText(""); + setVisible(); + okButton.setFocused(); +} + +void SingleSlotLoader::load() { + setVisible(false); + + switch(mode) { + case Mode::BsxSlotted: { + cartridge.loadBsxSlotted(basePath.text(), slotPath.text()); + break; + } + case Mode::Bsx: { + config.path.satellaviewBios = basePath.text(); + cartridge.loadBsx(basePath.text(), slotPath.text()); + break; + } + case Mode::SuperGameBoy: { + config.path.superGameBoyBios = basePath.text(); + cartridge.loadSuperGameBoy(basePath.text(), slotPath.text()); + break; + } + } +} + +// + +void DoubleSlotLoader::create() { + application.windows.append(this); + Window::create(0, 0, 256, 256); + setDefaultFont(application.proportionalFont); + + unsigned x = 5, y = 5, height = Style::TextBoxHeight, width = 365 + height; + + baseLabel.create(*this, x, y, 50, height, "Base:"); + basePath.create(*this, x + 50, y, 300, height); + baseBrowse.create(*this, x + 355, y, height, height, "..."); y += height + 5; + + slotALabel.create(*this, x, y, 50, height, "Slot A:"); + slotAPath.create(*this, x + 50, y, 300, height); + slotABrowse.create(*this, x + 355, y, height, height, "..."); y += height + 5; + + slotBLabel.create(*this, x, y, 50, height, "Slot B:"); + slotBPath.create(*this, x + 50, y, 300, height); + slotBBrowse.create(*this, x + 355, y, height, height, "..."); y += height + 5; + + okButton.create(*this, x + width - 85, y, 80, Style::ButtonHeight, "Ok"); y += Style::ButtonHeight + 5; + + setGeometry(160, 160, width, y); + + baseBrowse.onTick = []() { + fileBrowser.fileOpen(FileBrowser::Mode::Cartridge, [](string filename) { + doubleSlotLoader.basePath.setText(filename); + }); + }; + + slotABrowse.onTick = []() { + fileBrowser.fileOpen(FileBrowser::Mode::SufamiTurbo, [](string filename) { + doubleSlotLoader.slotAPath.setText(filename); + }); + }; + + slotBBrowse.onTick = []() { + fileBrowser.fileOpen(FileBrowser::Mode::SufamiTurbo, [](string filename) { + doubleSlotLoader.slotBPath.setText(filename); + }); + }; + + okButton.onTick = { &DoubleSlotLoader::load, this }; +} + +void DoubleSlotLoader::loadCartridgeSufamiTurbo() { + setTitle("Load Sufami Turbo Cartridge"); + basePath.setText(config.path.sufamiTurboBios); + slotAPath.setText(""); + slotBPath.setText(""); + setVisible(); + okButton.setFocused(); +} + +void DoubleSlotLoader::load() { + setVisible(false); + config.path.sufamiTurboBios = basePath.text(); + cartridge.loadSufamiTurbo(basePath.text(), slotAPath.text(), slotBPath.text()); +} diff --git a/bsnes/ui-phoenix/general/slot-loader.hpp b/bsnes/ui-phoenix/general/slot-loader.hpp new file mode 100755 index 00000000..8a327050 --- /dev/null +++ b/bsnes/ui-phoenix/general/slot-loader.hpp @@ -0,0 +1,38 @@ +struct SingleSlotLoader : Window { + Label baseLabel; + TextBox basePath; + Button baseBrowse; + Label slotLabel; + TextBox slotPath; + Button slotBrowse; + Button okButton; + + void create(); + void loadCartridgeBsxSlotted(); + void loadCartridgeBsx(); + void loadCartridgeSuperGameBoy(); + + enum class Mode : unsigned { BsxSlotted, Bsx, SuperGameBoy } mode; + void load(); +}; + +struct DoubleSlotLoader : Window { + Label baseLabel; + TextBox basePath; + Button baseBrowse; + Label slotALabel; + TextBox slotAPath; + Button slotABrowse; + Label slotBLabel; + TextBox slotBPath; + Button slotBBrowse; + Button okButton; + + void create(); + void loadCartridgeSufamiTurbo(); + + void load(); +}; + +extern SingleSlotLoader singleSlotLoader; +extern DoubleSlotLoader doubleSlotLoader; diff --git a/bsnes/ui-phoenix/interface.cpp b/bsnes/ui-phoenix/interface.cpp index e4790d99..98a99657 100755 --- a/bsnes/ui-phoenix/interface.cpp +++ b/bsnes/ui-phoenix/interface.cpp @@ -71,6 +71,20 @@ void Interface::video_refresh(const uint16_t *data, unsigned width, unsigned hei uint32_t *buffer; unsigned outpitch; + if(config.video.region == 0 && (height == 239 || height == 478)) { + //NTSC overscan compensation (center image, remove 15 lines) + data += 7 * 1024; + if(height == 239) height = 224; + if(height == 478) height = 448; + } + + if(config.video.region == 1 && (height == 224 || height == 448)) { + //PAL underscan compensation (center image, add 15 lines) + data -= 7 * 1024; + if(height == 224) height = 239; + if(height == 448) height = 478; + } + if(video.lock(buffer, outpitch, width, height)) { for(unsigned y = 0; y < height; y++) { uint32_t *output = buffer + y * (outpitch >> 2); diff --git a/bsnes/ui-phoenix/main.cpp b/bsnes/ui-phoenix/main.cpp index e3f1065f..3a48c2a7 100755 --- a/bsnes/ui-phoenix/main.cpp +++ b/bsnes/ui-phoenix/main.cpp @@ -33,6 +33,8 @@ void Application::main(int argc, char **argv) { monospaceFont.create("Liberation Mono", 8); #endif + SNES::system.init(&interface); + if(config.video.driver == "") config.video.driver = video.default_driver(); if(config.audio.driver == "") config.audio.driver = audio.default_driver(); if(config.input.driver == "") config.input.driver = video.default_driver(); @@ -40,6 +42,8 @@ void Application::main(int argc, char **argv) { palette.update(); mainWindow.create(); fileBrowser.create(); + singleSlotLoader.create(); + doubleSlotLoader.create(); videoSettings.create(); audioSettings.create(); inputSettings.create(); @@ -81,7 +85,6 @@ void Application::main(int argc, char **argv) { input.init(); } - SNES::system.init(&interface); if(argc == 2) cartridge.loadNormal(argv[1]); while(quit == false) { diff --git a/bsnes/ui-phoenix/utility/utility.cpp b/bsnes/ui-phoenix/utility/utility.cpp index 51adc5a2..d25d4514 100755 --- a/bsnes/ui-phoenix/utility/utility.cpp +++ b/bsnes/ui-phoenix/utility/utility.cpp @@ -35,26 +35,28 @@ void Utility::showMessage(const char *text) { } void Utility::setScale(unsigned scale) { + if(scale == 0) scale = config.video.scale; config.video.scale = scale; - unsigned width = 256 * scale; - unsigned height = 224 * scale; - if(config.video.aspectRatioCorrection) width *= 54.0 / 47.0; //PAL = 32.0 / 23.0 + unsigned width, height; + if(config.video.region == 0) { + width = 256 * scale; + height = 224 * scale; + if(config.video.aspectRatioCorrection) width *= 54.0 / 47.0; + } else { + width = 256 * scale; + height = 239 * scale; + if(config.video.aspectRatioCorrection) width *= 32.0 / 23.0; + } mainWindow.viewport.setGeometry(0, 0, width, height); mainWindow.setGeometry(128, 128, width, height); } -void Utility::setAspectRatioCorrection(bool aspectRatioCorrection) { - config.video.aspectRatioCorrection = aspectRatioCorrection; - setScale(config.video.scale); -} - void Utility::cartridgeLoaded() { SNES::system.power(); cheatEditor.load(cartridge.baseName); mainWindow.synchronize(); utility.setTitle(notdir(cartridge.baseName)); utility.showMessage(string("Loaded ", notdir(cartridge.baseName))); - config.path.current = dir(cartridge.baseName); } void Utility::cartridgeUnloaded() { @@ -65,7 +67,9 @@ void Utility::cartridgeUnloaded() { void Utility::loadCartridgeNormal() { if(config.settings.useNativeDialogs == false) { - fileBrowser.fileOpen(config.path.current); + fileBrowser.fileOpen(FileBrowser::Mode::Cartridge, [](string filename) { + cartridge.loadNormal(filename); + }); } else { string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", config.path.current); if(filename != "") { diff --git a/bsnes/ui-phoenix/utility/utility.hpp b/bsnes/ui-phoenix/utility/utility.hpp index c8b0e7cd..589af593 100755 --- a/bsnes/ui-phoenix/utility/utility.hpp +++ b/bsnes/ui-phoenix/utility/utility.hpp @@ -4,8 +4,7 @@ struct Utility : property { void setStatus(const char *text); void showMessage(const char *text); - void setScale(unsigned scale); - void setAspectRatioCorrection(bool aspectRatioCorrection); + void setScale(unsigned scale = 0); void cartridgeLoaded(); void cartridgeUnloaded();