Update to v076r05 release.

byuu says:

Changelog:
- QMenu::setVisible() does nothing, have to use
  QMenu::menuAction::setVisible()
- improved path system, especially for ST games (states will be
  /path/to/slotA+notdir(slotB).ext, saves are per-game and per-path)
- paths are now valid when you load just the BS-X/ST/SGB BIOSes with no
  carts inserted; maybe useful for BS-X I guess
- removed video filter and pixel shader code from video settings dialog
- added Settings->Video Filter and Settings->Video Shader menu lists
- fixed the SaI family of filters in lores-mode only; although I don't
  really know how or why the change fixed them, the code is too vague

The menu list for the video filters and shaders are populated from
either base/filters and base/shaders, or user/.config/bsnes/filters and
user/.config/bsnes/shaders. It tries the first, and if it does not find
anything it tries the second, just like the configuration files.

That meant doing away with multiple folders for the shaders, so now the
shaders have a suffix to indicate what driver uses them, eg
"Curvature.OpenGL.shader" and "Sepia.Direct3D.shader" -- probably nicer
to use GLSL/HLSL, but using the driver name lets me sub in the currently
loaded video driver with no special casing. So the filter if you have eg
OpenGL loaded is "*.OpenGL.shader"; and for SDL you get "*.SDL.shader",
which will obviously not be there as the non-GL-based SDL driver doesn't
support shaders.

If there are no filters or no shaders available, the menu options do not
show up. The lists are not radio items with active item ticked states
just yet, but they will be.
This commit is contained in:
Tim Allen 2011-03-14 22:04:21 +11:00
parent 8b7dd89059
commit d5cd21eb0c
26 changed files with 215 additions and 160 deletions

View File

@ -28,7 +28,7 @@ void pAction::setFont(Font &font) {
void pAction::setVisible(bool visible) { void pAction::setVisible(bool visible) {
if(dynamic_cast<Menu*>(&action)) { if(dynamic_cast<Menu*>(&action)) {
((Menu&)action).p.qtMenu->setVisible(visible); ((Menu&)action).p.qtMenu->menuAction()->setVisible(visible);
} else if(dynamic_cast<Separator*>(&action)) { } else if(dynamic_cast<Separator*>(&action)) {
((Separator&)action).p.qtAction->setVisible(visible); ((Separator&)action).p.qtAction->setVisible(visible);
} else if(dynamic_cast<Item*>(&action)) { } else if(dynamic_cast<Item*>(&action)) {

View File

@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
** Meta object code from reading C++ file 'qt.moc.hpp' ** Meta object code from reading C++ file 'qt.moc.hpp'
** **
** Created: Thu Feb 24 07:36:07 2011 ** Created: Sun Mar 13 14:53:22 2011
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2) ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
** **
** WARNING! All changes made in this file will be lost! ** WARNING! All changes made in this file will be lost!
*****************************************************************************/ *****************************************************************************/
@ -10,7 +10,7 @@
#if !defined(Q_MOC_OUTPUT_REVISION) #if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qt.moc.hpp' doesn't include <QObject>." #error "The header file 'qt.moc.hpp' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 62 #elif Q_MOC_OUTPUT_REVISION != 62
#error "This file was generated using the moc from 4.6.2. It" #error "This file was generated using the moc from 4.7.0. It"
#error "cannot be used with the include files from this version of Qt." #error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)" #error "(The moc has changed too much.)"
#endif #endif
@ -19,7 +19,7 @@ QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_pWindow[] = { static const uint qt_meta_data_pWindow[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
0, 0, // methods 0, 0, // methods
@ -70,7 +70,7 @@ int pWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pItem[] = { static const uint qt_meta_data_pItem[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -131,7 +131,7 @@ int pItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pCheckItem[] = { static const uint qt_meta_data_pCheckItem[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -192,7 +192,7 @@ int pCheckItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pRadioItem[] = { static const uint qt_meta_data_pRadioItem[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -253,7 +253,7 @@ int pRadioItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pButton[] = { static const uint qt_meta_data_pButton[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -314,7 +314,7 @@ int pButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pCheckBox[] = { static const uint qt_meta_data_pCheckBox[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -375,7 +375,7 @@ int pCheckBox::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pComboBox[] = { static const uint qt_meta_data_pComboBox[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -436,7 +436,7 @@ int pComboBox::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pHexEdit[] = { static const uint qt_meta_data_pHexEdit[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -497,7 +497,7 @@ int pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pHorizontalSlider[] = { static const uint qt_meta_data_pHorizontalSlider[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -558,7 +558,7 @@ int pHorizontalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pLineEdit[] = { static const uint qt_meta_data_pLineEdit[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
2, 14, // methods 2, 14, // methods
@ -621,7 +621,7 @@ int pLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pListView[] = { static const uint qt_meta_data_pListView[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
3, 14, // methods 3, 14, // methods
@ -687,7 +687,7 @@ int pListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pRadioBox[] = { static const uint qt_meta_data_pRadioBox[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -748,7 +748,7 @@ int pRadioBox::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pTextEdit[] = { static const uint qt_meta_data_pTextEdit[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -809,7 +809,7 @@ int pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_pVerticalSlider[] = { static const uint qt_meta_data_pVerticalSlider[] = {
// content: // content:
4, // revision 5, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods

View File

@ -37,7 +37,7 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
if(ram_size > 0) { if(ram_size > 0) {
ram.map(allocate<uint8>(ram_size, 0xff), ram_size); ram.map(allocate<uint8>(ram_size, 0xff), ram_size);
nvram.append({ "srm", ram.data(), ram.size() }); nvram.append({ ".srm", ram.data(), ram.size() });
} }
rom.write_protect(true); rom.write_protect(true);

View File

@ -13,9 +13,10 @@ public:
PAL, PAL,
}; };
enum class Slot : unsigned { enum class Path : unsigned {
Base, Base,
Bsx, Bsx,
SufamiTurbo,
SufamiTurboA, SufamiTurboA,
SufamiTurboB, SufamiTurboB,
GameBoy, GameBoy,
@ -54,10 +55,10 @@ public:
const string id; const string id;
uint8_t *data; uint8_t *data;
unsigned size; unsigned size;
Slot slot; Path path;
NonVolatileRAM() : id(""), data(0), size(0), slot(Slot::Base) {} NonVolatileRAM() : id(""), data(0), size(0), path(Path::Base) {}
NonVolatileRAM(const string id, uint8_t *data, unsigned size, Slot slot = Slot::Base) NonVolatileRAM(const string id, uint8_t *data, unsigned size, Path path = Path::Base)
: id(id), data(data), size(size), slot(slot) {} : id(id), data(data), size(size), path(path) {}
}; };
linear_vector<NonVolatileRAM> nvram; linear_vector<NonVolatileRAM> nvram;

View File

@ -274,7 +274,7 @@ void Cartridge::xml_parse_necdsp(xml_element &root) {
unsigned filesize = promsize * 3 + dromsize * 2; unsigned filesize = promsize * 3 + dromsize * 2;
file fp; file fp;
if(fp.open(system.interface->path(Slot::NECDSP, program), file::mode::read)) { if(fp.open(system.interface->path(Path::NECDSP, program), file::mode::read)) {
if(fp.size() == filesize) { if(fp.size() == filesize) {
for(unsigned n = 0; n < promsize; n++) necdsp.programROM[n] = fp.readm(3); for(unsigned n = 0; n < promsize; n++) necdsp.programROM[n] = fp.readm(3);
for(unsigned n = 0; n < dromsize; n++) necdsp.dataROM[n] = fp.readm(2); for(unsigned n = 0; n < dromsize; n++) necdsp.dataROM[n] = fp.readm(2);

View File

@ -8,11 +8,11 @@ void BSXCartridge::init() {
void BSXCartridge::load() { void BSXCartridge::load() {
sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024); sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024);
sram.write_protect(false); sram.write_protect(false);
cartridge.nvram.append({ "bss", sram.data(), sram.size() }); cartridge.nvram.append({ ".bss", sram.data(), sram.size() });
psram.map(allocate<uint8>(512 * 1024, 0xff), 512 * 1024); psram.map(allocate<uint8>(512 * 1024, 0xff), 512 * 1024);
psram.write_protect(false); psram.write_protect(false);
cartridge.nvram.append({ "bsp", psram.data(), psram.size() }); cartridge.nvram.append({ ".bsp", psram.data(), psram.size() });
} }
void BSXCartridge::unload() { void BSXCartridge::unload() {

View File

@ -50,7 +50,7 @@ void MSU1::init() {
void MSU1::load() { void MSU1::load() {
if(datafile.open()) datafile.close(); if(datafile.open()) datafile.close();
datafile.open(system.interface->path(Cartridge::Slot::MSU1, ".msu"), file::mode::read); datafile.open(system.interface->path(Cartridge::Path::MSU1, ".msu"), file::mode::read);
} }
void MSU1::unload() { void MSU1::unload() {
@ -133,7 +133,7 @@ void MSU1::mmio_write(unsigned addr, uint8 data) {
if(addr == 0x2005) { if(addr == 0x2005) {
mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
if(audiofile.open()) audiofile.close(); if(audiofile.open()) audiofile.close();
if(audiofile.open(system.interface->path(Cartridge::Slot::MSU1, { "-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) { if(audiofile.open(system.interface->path(Cartridge::Path::MSU1, { "-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) {
uint32 header = audiofile.readm(4); uint32 header = audiofile.readm(4);
if(header != 0x4d535531) { //verify 'MSU1' header if(header != 0x4d535531) { //verify 'MSU1' header
audiofile.close(); audiofile.close();

View File

@ -16,12 +16,12 @@ void MSU1::serialize(serializer &s) {
s.integer(mmio.audio_play); s.integer(mmio.audio_play);
if(datafile.open()) datafile.close(); if(datafile.open()) datafile.close();
if(datafile.open(system.interface->path(Cartridge::Slot::MSU1, ".msu"), file::mode::read)) { if(datafile.open(system.interface->path(Cartridge::Path::MSU1, ".msu"), file::mode::read)) {
datafile.seek(mmio.data_offset); datafile.seek(mmio.data_offset);
} }
if(audiofile.open()) audiofile.close(); if(audiofile.open()) audiofile.close();
if(audiofile.open(system.interface->path(Cartridge::Slot::MSU1, { "-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) { if(audiofile.open(system.interface->path(Cartridge::Path::MSU1, { "-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) {
audiofile.seek(mmio.audio_offset); audiofile.seek(mmio.audio_offset);
} }
} }

View File

@ -79,7 +79,7 @@ void Serial::init() {
void Serial::load() { void Serial::load() {
if(opened()) close(); if(opened()) close();
string basename = system.interface->path(Cartridge::Slot::Serial, ""); string basename = system.interface->path(Cartridge::Path::Serial, "");
string name = notdir(basename); string name = notdir(basename);
string path = dir(basename); string path = dir(basename);
if(open(name, path)) { if(open(name, path)) {

View File

@ -11,13 +11,13 @@ void SufamiTurbo::load() {
slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
if(slotA.rom.data()) { if(slotA.rom.data()) {
cartridge.nvram.append({ "sts", slotA.ram.data(), slotA.ram.size(), Cartridge::Slot::SufamiTurboA }); cartridge.nvram.append({ ".sts", slotA.ram.data(), slotA.ram.size(), Cartridge::Path::SufamiTurboA });
} else { } else {
slotA.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotA.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }
if(slotB.rom.data()) { if(slotB.rom.data()) {
cartridge.nvram.append({ "sts", slotB.ram.data(), slotB.ram.size(), Cartridge::Slot::SufamiTurboB }); cartridge.nvram.append({ ".sts", slotB.ram.data(), slotB.ram.size(), Cartridge::Path::SufamiTurboB });
} else { } else {
slotB.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotB.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }

View File

@ -6,5 +6,5 @@ public:
virtual int16_t input_poll(bool port, Input::Device device, unsigned index, unsigned id) { return 0; } virtual int16_t input_poll(bool port, Input::Device device, unsigned index, unsigned id) { return 0; }
virtual void message(const string &text) { print(text, "\n"); } virtual void message(const string &text) { print(text, "\n"); }
virtual string path(Cartridge::Slot slot, const string &path) { return path; }; virtual string path(Cartridge::Path path, const string &hint) { return hint; };
}; };

View File

@ -1,7 +1,7 @@
namespace SNES { namespace SNES {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const char Version[] = "076.04"; static const char Version[] = "076.05";
static const unsigned SerializerVersion = 18; static const unsigned SerializerVersion = 18;
} }
} }

View File

@ -73,7 +73,7 @@ bool Cartridge::loadSuperGameBoy(const char *basename, const char *slotname) {
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { baseXML, "" }); SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { baseXML, "" });
foreach(memory, SNES::cartridge.nvram) loadMemory(memory); foreach(memory, SNES::cartridge.nvram) loadMemory(memory);
if(GameBoy::cartridge.info.battery && fp.open(path.load(SNES::Cartridge::Slot::GameBoy, "sav"), file::mode::read)) { if(GameBoy::cartridge.info.battery && fp.open(path.load(SNES::Cartridge::Path::GameBoy, ".sav"), file::mode::read)) {
fp.read(GameBoy::cartridge.ramdata, min(GameBoy::cartridge.ramsize, fp.size())); fp.read(GameBoy::cartridge.ramdata, min(GameBoy::cartridge.ramsize, fp.size()));
fp.close(); fp.close();
} }
@ -89,7 +89,7 @@ void Cartridge::unload() {
foreach(memory, SNES::cartridge.nvram) saveMemory(memory); foreach(memory, SNES::cartridge.nvram) saveMemory(memory);
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) { if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) {
file fp; file fp;
if(GameBoy::cartridge.info.battery && fp.open(path.load(SNES::Cartridge::Slot::GameBoy, "sav"), file::mode::write)) { if(GameBoy::cartridge.info.battery && fp.open(path.load(SNES::Cartridge::Path::GameBoy, ".sav"), file::mode::write)) {
fp.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize); fp.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
fp.close(); fp.close();
} }
@ -133,7 +133,7 @@ bool Cartridge::loadCartridge(SNES::MappedRAM &memory, string &XML, const char *
bool Cartridge::loadMemory(SNES::Cartridge::NonVolatileRAM &memory) { bool Cartridge::loadMemory(SNES::Cartridge::NonVolatileRAM &memory) {
if(memory.size == 0) return true; if(memory.size == 0) return true;
string filename = path.load(memory.slot, memory.id); string filename = path.load(memory.path, memory.id);
file fp; file fp;
if(fp.open(filename, file::mode::read) == false) return false; if(fp.open(filename, file::mode::read) == false) return false;
fp.read(memory.data, min(memory.size, fp.size())); fp.read(memory.data, min(memory.size, fp.size()));
@ -143,7 +143,7 @@ bool Cartridge::loadMemory(SNES::Cartridge::NonVolatileRAM &memory) {
bool Cartridge::saveMemory(SNES::Cartridge::NonVolatileRAM &memory) { bool Cartridge::saveMemory(SNES::Cartridge::NonVolatileRAM &memory) {
if(memory.size == 0) return true; if(memory.size == 0) return true;
string filename = path.load(memory.slot, memory.id); string filename = path.load(memory.path, memory.id);
file fp; file fp;
if(fp.open(filename, file::mode::write) == false) return false; if(fp.open(filename, file::mode::write) == false) return false;
fp.write(memory.data, memory.size); fp.write(memory.data, memory.size);

View File

@ -54,7 +54,7 @@ void Console::write(const string &text, bool echo) {
void Console::tracerEnable(bool state) { void Console::tracerEnable(bool state) {
if(state == true) { if(state == true) {
logfile.open(path.load(SNES::Cartridge::Slot::Base, "log"), file::mode::write); logfile.open(path.load(SNES::Cartridge::Slot::Base, ".log"), file::mode::write);
} else { } else {
logfile.close(); logfile.close();
} }

View File

@ -126,6 +126,24 @@ void MainWindow::create() {
settingsVideoModePAL.setText("PAL"); settingsVideoModePAL.setText("PAL");
settingsVideoMode.append(settingsVideoModePAL); settingsVideoMode.append(settingsVideoModePAL);
settingsVideoFilter.setText("Video Filter");
settings.append(settingsVideoFilter);
settingsVideoFilterNone.setText("None");
settingsVideoFilter.append(settingsVideoFilterNone);
settingsVideoFilter.append(settingsVideoFilterSeparator);
settingsVideoShader.setText("Video Shader");
settings.append(settingsVideoShader);
settingsVideoShaderNone.setText("None");
settingsVideoShader.append(settingsVideoShaderNone);
settingsVideoShader.append(settingsVideoShaderSeparator);
setupFiltersAndShaders();
RadioItem::group( RadioItem::group(
settingsVideoModeNTSC, settingsVideoModePAL settingsVideoModeNTSC, settingsVideoModePAL
); );
@ -302,6 +320,16 @@ void MainWindow::create() {
settingsVideoModeNTSC.onTick = []() { config.video.region = 0; utility.setScale(); }; settingsVideoModeNTSC.onTick = []() { config.video.region = 0; utility.setScale(); };
settingsVideoModePAL.onTick = []() { config.video.region = 1; utility.setScale(); }; settingsVideoModePAL.onTick = []() { config.video.region = 1; utility.setScale(); };
settingsVideoFilterNone.onTick = []() {
config.video.filter = "";
utility.setFilter();
};
settingsVideoShaderNone.onTick = []() {
config.video.shader = "";
utility.setShader();
};
settingsSmoothVideo.onTick = []() { settingsSmoothVideo.onTick = []() {
config.video.smooth = mainWindow.settingsSmoothVideo.checked(); config.video.smooth = mainWindow.settingsSmoothVideo.checked();
video.set(Video::Filter, (unsigned)config.video.smooth); video.set(Video::Filter, (unsigned)config.video.smooth);
@ -373,3 +401,60 @@ void MainWindow::synchronize() {
toolsStateLoad.setEnabled(true); toolsStateLoad.setEnabled(true);
} }
} }
void MainWindow::setupFiltersAndShaders() {
string folderPath;
lstring files;
folderPath = { path.base, "filters/" };
files = directory::files(folderPath, "*.filter");
if(files.size() == 0) {
folderPath = { path.user, ".config/bsnes/filters/" };
files = directory::files(folderPath, "*.filter");
}
foreach(filename, files) {
settingsVideoFilterName.append({ folderPath, filename });
}
if(settingsVideoFilterName.size() == 0) {
settingsVideoFilter.setVisible(false);
config.video.filter = ""; //as the list (and thus the 'None' option) is invisible,
utility.setFilter(); //erase any previously saved filter name
} else {
settingsVideoFilterItem = new Item[settingsVideoFilterName.size()];
foreach(filename, settingsVideoFilterName, n) {
settingsVideoFilterItem[n].onTick = [n]() {
config.video.filter = mainWindow.settingsVideoFilterName[n];
utility.setFilter();
};
settingsVideoFilterItem[n].setText(nall::basename(notdir(filename)));
settingsVideoFilter.append(settingsVideoFilterItem[n]);
}
}
folderPath = { path.base, "shaders/" };
files = directory::files(folderPath, { "*.", config.video.driver, ".shader" });
if(files.size() == 0) {
folderPath = { path.user, ".config/bsnes/shaders/" };
files = directory::files(folderPath, { "*.", config.video.driver, ".shader" });
}
foreach(filename, files) {
settingsVideoShaderName.append({ folderPath, filename });
}
if(settingsVideoShaderName.size() == 0) {
settingsVideoShader.setVisible(false);
config.video.shader = "";
utility.setShader();
} else {
settingsVideoShaderItem = new Item[settingsVideoShaderName.size()];
foreach(filename, settingsVideoShaderName, n) {
settingsVideoShaderItem[n].onTick = [n]() {
config.video.shader = mainWindow.settingsVideoShaderName[n];
utility.setShader();
};
settingsVideoShaderItem[n].setText(nall::basename(nall::basename(notdir(filename))));
settingsVideoShader.append(settingsVideoShaderItem[n]);
}
}
}

View File

@ -36,6 +36,19 @@ struct MainWindow : TopLevelWindow {
Separator settingsVideoModeSeparator2; Separator settingsVideoModeSeparator2;
RadioItem settingsVideoModeNTSC; RadioItem settingsVideoModeNTSC;
RadioItem settingsVideoModePAL; RadioItem settingsVideoModePAL;
Menu settingsVideoFilter;
Item settingsVideoFilterNone;
Separator settingsVideoFilterSeparator;
Item *settingsVideoFilterItem;
lstring settingsVideoFilterName;
Menu settingsVideoShader;
Item settingsVideoShaderNone;
Separator settingsVideoShaderSeparator;
Item *settingsVideoShaderItem;
lstring settingsVideoShaderName;
CheckItem settingsSmoothVideo; CheckItem settingsSmoothVideo;
Separator settingsSeparator1; Separator settingsSeparator1;
CheckItem settingsSynchronizeVideo; CheckItem settingsSynchronizeVideo;
@ -76,6 +89,7 @@ struct MainWindow : TopLevelWindow {
void create(); void create();
void synchronize(); void synchronize();
void setupFiltersAndShaders();
}; };
extern MainWindow mainWindow; extern MainWindow mainWindow;

View File

@ -138,6 +138,6 @@ void Interface::message(const string &text) {
MessageWindow::information(mainWindow, text); MessageWindow::information(mainWindow, text);
} }
string Interface::path(SNES::Cartridge::Slot slot, const string &pathname) { string Interface::path(SNES::Cartridge::Path path, const string &hint) {
return ::path.load(slot, pathname); return ::path.load(path, hint);
} }

View File

@ -21,7 +21,7 @@ struct Interface : public SNES::Interface {
int16_t input_poll(bool port, SNES::Input::Device device, unsigned index, unsigned id); int16_t input_poll(bool port, SNES::Input::Device device, unsigned index, unsigned id);
void message(const string &text); void message(const string &text);
string path(SNES::Cartridge::Slot slot, const string &path); string path(SNES::Cartridge::Path path, const string &hint);
}; };
extern Palette palette; extern Palette palette;

View File

@ -27,9 +27,6 @@ string Path::load(const string &path) {
if(path == "st") value = st; if(path == "st") value = st;
if(path == "gb") value = gb; if(path == "gb") value = gb;
if(path == "filter") value = filter;
if(path == "shader") value = shader;
if(value.beginswith("recent/")) value.ltrim<1>("recent/"); if(value.beginswith("recent/")) value.ltrim<1>("recent/");
if(value == "") value = base; if(value == "") value = base;
return value; return value;
@ -43,9 +40,6 @@ void Path::save(const string &path, const string &value) {
if(path == "st") output = &st; if(path == "st") output = &st;
if(path == "gb") output = &gb; if(path == "gb") output = &gb;
if(path == "filter") output = &filter;
if(path == "shader") output = &shader;
if(output) { if(output) {
string &s = *output; string &s = *output;
if(s.beginswith("recent/") == false && s != "") return; if(s.beginswith("recent/") == false && s != "") return;
@ -54,36 +48,63 @@ void Path::save(const string &path, const string &value) {
} }
} }
string Path::load(SNES::Cartridge::Slot slot, const string &type, const string &suffix) { string Path::load(SNES::Cartridge::Path pathHint, const string &hint) {
string romPath; string romPath;
switch(slot) { switch(pathHint) {
case SNES::Cartridge::Slot::Base: romPath = cartridge.baseName; break; case SNES::Cartridge::Path::Base: {
case SNES::Cartridge::Slot::Bsx: romPath = cartridge.bsxName; break; romPath = cartridge.baseName;
case SNES::Cartridge::Slot::SufamiTurboA: romPath = cartridge.sufamiTurboAName; break; break;
case SNES::Cartridge::Slot::SufamiTurboB: romPath = cartridge.sufamiTurboBName; break; }
case SNES::Cartridge::Slot::GameBoy: romPath = cartridge.gameBoyName; break; case SNES::Cartridge::Path::Bsx: {
romPath = cartridge.bsxName != "" ? cartridge.bsxName : cartridge.baseName;
break;
}
case SNES::Cartridge::Path::SufamiTurbo: {
if(cartridge.sufamiTurboAName == "" && cartridge.sufamiTurboBName == "") {
romPath = cartridge.baseName;
} else if(cartridge.sufamiTurboAName != "" && cartridge.sufamiTurboBName == "") {
romPath = cartridge.sufamiTurboAName;
} else if(cartridge.sufamiTurboAName == "" && cartridge.sufamiTurboBName != "") {
romPath = cartridge.sufamiTurboBName;
} else {
romPath = { cartridge.sufamiTurboAName, "+", notdir(cartridge.sufamiTurboBName) };
}
break;
}
case SNES::Cartridge::Path::SufamiTurboA: {
romPath = cartridge.sufamiTurboAName != "" ? cartridge.sufamiTurboAName : cartridge.baseName;
break;
}
case SNES::Cartridge::Path::SufamiTurboB: {
romPath = cartridge.sufamiTurboBName != "" ? cartridge.sufamiTurboBName : cartridge.baseName;
break;
}
case SNES::Cartridge::Path::GameBoy: {
romPath = cartridge.gameBoyName != "" ? cartridge.gameBoyName : cartridge.baseName;
break;
}
case SNES::Cartridge::Slot::NECDSP: romPath = cartridge.baseName; break; case SNES::Cartridge::Path::NECDSP: romPath = cartridge.baseName; break;
case SNES::Cartridge::Slot::MSU1: romPath = cartridge.baseName; break; case SNES::Cartridge::Path::MSU1: romPath = cartridge.baseName; break;
case SNES::Cartridge::Slot::Serial: romPath = cartridge.baseName; break; case SNES::Cartridge::Path::Serial: romPath = cartridge.baseName; break;
} }
string path = romPath; string path = romPath;
if(slot == SNES::Cartridge::Slot::NECDSP && necdsp != "") path = necdsp; if(pathHint == SNES::Cartridge::Path::NECDSP && necdsp != "") path = necdsp;
if(slot == SNES::Cartridge::Slot::MSU1 && msu1 != "") path = string(msu1, notdir(path)); if(pathHint == SNES::Cartridge::Path::MSU1 && msu1 != "") path = string(msu1, notdir(path));
if(slot == SNES::Cartridge::Slot::Serial && serial != "") path = string(serial, notdir(path)); if(pathHint == SNES::Cartridge::Path::Serial && serial != "") path = string(serial, notdir(path));
if(type == "srm" && srm != "") path = string(srm, notdir(path)); if(hint == ".srm" && srm != "") path = string(srm, notdir(path));
if(type == "bsp" && bsp != "") path = string(bsp, notdir(path)); if(hint == ".bsp" && bsp != "") path = string(bsp, notdir(path));
if(type == "bss" && bss != "") path = string(bss, notdir(path)); if(hint == ".bss" && bss != "") path = string(bss, notdir(path));
if(type == "sts" && sts != "") path = string(sts, notdir(path)); if(hint == ".sts" && sts != "") path = string(sts, notdir(path));
if(type == "sav" && sav != "") path = string(sav, notdir(path)); if(hint == ".sav" && sav != "") path = string(sav, notdir(path));
if(type == "rtc" && rtc != "") path = string(rtc, notdir(path)); if(hint == ".rtc" && rtc != "") path = string(rtc, notdir(path));
if(type == "bsa" && bsa != "") path = string(bsa, notdir(path)); if(hint == ".bsa" && bsa != "") path = string(bsa, notdir(path));
if(type == "bst" && bst != "") path = string(bst, notdir(path)); if(hint.endswith(".bst") && bst != "") path = string(bst, notdir(path));
if(type == "cht" && cht != "") path = string(cht, notdir(path)); if(hint == ".cht" && cht != "") path = string(cht, notdir(path));
if(type == "log" && log != "") path = string(log, notdir(path)); if(hint == ".log" && log != "") path = string(log, notdir(path));
if(path.beginswith("user/")) { if(path.beginswith("user/")) {
path.ltrim<1>("user/"); path.ltrim<1>("user/");
@ -105,11 +126,11 @@ string Path::load(SNES::Cartridge::Slot slot, const string &type, const string &
path = string(dir(base), path); path = string(dir(base), path);
} }
if(slot == SNES::Cartridge::Slot::NECDSP) return { dir(path), type }; if(pathHint == SNES::Cartridge::Path::NECDSP) return { dir(path), hint };
if(slot == SNES::Cartridge::Slot::MSU1) return { path, type }; if(pathHint == SNES::Cartridge::Path::MSU1) return { path, hint };
if(slot == SNES::Cartridge::Slot::Serial) return { path, type }; if(pathHint == SNES::Cartridge::Path::Serial) return { path, hint };
return { path, suffix, ".", type }; return { path, hint };
} }
void Path::load() { void Path::load() {
@ -126,9 +147,6 @@ Path::Path() {
attach(st = "", "st"); attach(st = "", "st");
attach(gb = "", "gb"); attach(gb = "", "gb");
attach(filter = "", "filter");
attach(shader = "", "shader");
attach(satellaviewBios = "", "satellaviewBios"); attach(satellaviewBios = "", "satellaviewBios");
attach(sufamiTurboBios = "", "sufamiTurboBios"); attach(sufamiTurboBios = "", "sufamiTurboBios");
attach(superGameBoyBios = "", "superGameBoyBios"); attach(superGameBoyBios = "", "superGameBoyBios");

View File

@ -7,9 +7,6 @@ struct Path : public configuration {
string st; string st;
string gb; string gb;
string filter;
string shader;
string satellaviewBios; string satellaviewBios;
string sufamiTurboBios; string sufamiTurboBios;
string superGameBoyBios; string superGameBoyBios;
@ -33,7 +30,7 @@ struct Path : public configuration {
string home(const string &filename); string home(const string &filename);
string load(const string &path); string load(const string &path);
void save(const string &path, const string &value); void save(const string &path, const string &value);
string load(SNES::Cartridge::Slot slot, const string &type, const string &suffix = ""); string load(SNES::Cartridge::Path path, const string &hint);
void load(); void load();
void save(); void save();

View File

@ -19,16 +19,6 @@ void VideoSettings::create() {
fullscreenScale.setText("Scale"); fullscreenScale.setText("Scale");
fullscreenStretch.setText("Stretch"); fullscreenStretch.setText("Stretch");
RadioBox::group(fullscreenCenter, fullscreenScale, fullscreenStretch); RadioBox::group(fullscreenCenter, fullscreenScale, fullscreenStretch);
filterLabel.setText("Video Filter :.");
filterLabel.setFont(application.proportionalFontBold);
filterPath.setEditable(false);
filterPath.setText(config.video.filter);
filterSelect.setText("...");
shaderLabel.setText("Pixel Shader :.");
shaderLabel.setFont(application.proportionalFontBold);
shaderPath.setEditable(false);
shaderPath.setText(config.video.shader);
shaderSelect.setText("...");
layout.setMargin(5); layout.setMargin(5);
layout.append(colorAdjustmentLabel, 0, Style::LabelHeight); layout.append(colorAdjustmentLabel, 0, Style::LabelHeight);
@ -49,17 +39,7 @@ void VideoSettings::create() {
fullscreenLayout.append(fullscreenCenter, 0, 0); fullscreenLayout.append(fullscreenCenter, 0, 0);
fullscreenLayout.append(fullscreenScale, 0, 0); fullscreenLayout.append(fullscreenScale, 0, 0);
fullscreenLayout.append(fullscreenStretch, 0, 0); fullscreenLayout.append(fullscreenStretch, 0, 0);
layout.append(fullscreenLayout, 0, Style::CheckBoxHeight, 5); layout.append(fullscreenLayout, 0, Style::CheckBoxHeight);
layout.append(filterLabel, 0, Style::LabelHeight);
filterLayout.append(filterPath, 0, 0, 5);
filterLayout.append(filterClear, Style::LineEditHeight, 0, 5);
filterLayout.append(filterSelect, Style::LineEditHeight, 0);
layout.append(filterLayout, 0, Style::LineEditHeight, 5);
layout.append(shaderLabel, 0, Style::LabelHeight);
shaderLayout.append(shaderPath, 0, 0, 5);
shaderLayout.append(shaderClear, Style::LineEditHeight, 0, 5);
shaderLayout.append(shaderSelect, Style::LineEditHeight, 0);
layout.append(shaderLayout, 0, Style::LineEditHeight);
setGeometry({ 0, 0, 480, layout.minimumHeight() }); setGeometry({ 0, 0, 480, layout.minimumHeight() });
append(layout); append(layout);
@ -87,34 +67,6 @@ void VideoSettings::create() {
fullscreenCenter.onTick = []() { config.video.fullscreenScale = 0; }; fullscreenCenter.onTick = []() { config.video.fullscreenScale = 0; };
fullscreenScale.onTick = []() { config.video.fullscreenScale = 1; }; fullscreenScale.onTick = []() { config.video.fullscreenScale = 1; };
fullscreenStretch.onTick = []() { config.video.fullscreenScale = 2; }; fullscreenStretch.onTick = []() { config.video.fullscreenScale = 2; };
filterClear.onTick = []() {
config.video.filter = "";
videoSettings.filterPath.setText(config.video.filter);
utility.setFilter();
};
filterSelect.onTick = []() {
fileBrowser.fileOpen(FileBrowser::Mode::Filter, [](string filename) {
config.video.filter = filename;
videoSettings.filterPath.setText(config.video.filter);
utility.setFilter();
});
};
shaderClear.onTick = []() {
config.video.shader = "";
videoSettings.shaderPath.setText(config.video.shader);
utility.setShader();
};
shaderSelect.onTick = []() {
fileBrowser.fileOpen(FileBrowser::Mode::Shader, [](string filename) {
config.video.shader = filename;
videoSettings.shaderPath.setText(config.video.shader);
utility.setShader();
});
};
} }
void VideoSettings::adjust() { void VideoSettings::adjust() {

View File

@ -25,18 +25,6 @@ struct VideoSettings : TopLevelWindow {
RadioBox fullscreenScale; RadioBox fullscreenScale;
RadioBox fullscreenStretch; RadioBox fullscreenStretch;
Label filterLabel;
HorizontalLayout filterLayout;
LineEdit filterPath;
Button filterClear;
Button filterSelect;
Label shaderLabel;
HorizontalLayout shaderLayout;
LineEdit shaderPath;
Button shaderClear;
Button shaderSelect;
void create(); void create();
void adjust(); void adjust();
}; };

View File

@ -12,7 +12,7 @@ void CheatEditor::load() {
unsigned n = 0; unsigned n = 0;
string data; string data;
data.readfile(path.load(utility.stateSlot(), "cht")); data.readfile(path.load(utility.slotPath(), ".cht"));
xml_element document = xml_parse(data); xml_element document = xml_parse(data);
foreach(head, document.element) { foreach(head, document.element) {
if(head.name == "cartridge") { if(head.name == "cartridge") {
@ -52,12 +52,12 @@ void CheatEditor::save() {
} }
} }
if(lastSave == -1) { if(lastSave == -1) {
unlink(path.load(utility.stateSlot(), "cht")); unlink(path.load(utility.slotPath(), ".cht"));
return; return;
} }
file fp; file fp;
if(fp.open(path.load(utility.stateSlot(), "cht"), file::mode::write)) { if(fp.open(path.load(utility.slotPath(), ".cht"), file::mode::write)) {
fp.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fp.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fp.print(string("<cartridge sha256=\"", SNES::cartridge.sha256(), "\">\n")); fp.print(string("<cartridge sha256=\"", SNES::cartridge.sha256(), "\">\n"));
for(unsigned i = 0; i <= lastSave; i++) { for(unsigned i = 0; i <= lastSave; i++) {

View File

@ -60,7 +60,7 @@ void StateManager::load() {
} }
file fp; file fp;
if(fp.open(path.load(utility.stateSlot(), "bsa"), file::mode::read)) { if(fp.open(path.load(utility.slotPath(), ".bsa"), file::mode::read)) {
if(fp.readl(4) == 0x31415342) { if(fp.readl(4) == 0x31415342) {
if(fp.readl(4) == SNES::Info::SerializerVersion) { if(fp.readl(4) == SNES::Info::SerializerVersion) {
for(unsigned i = 0; i < 32; i++) { for(unsigned i = 0; i < 32; i++) {
@ -84,10 +84,10 @@ void StateManager::save() {
} }
if(hasSave == false) { if(hasSave == false) {
unlink(path.load(utility.stateSlot(), "bsa")); unlink(path.load(utility.slotPath(), ".bsa"));
} else { } else {
file fp; file fp;
if(fp.open(path.load(utility.stateSlot(), "bsa"), file::mode::write)) { if(fp.open(path.load(utility.slotPath(), ".bsa"), file::mode::write)) {
fp.writel(0x31415342, 4); //'BSA1' fp.writel(0x31415342, 4); //'BSA1'
fp.writel(SNES::Info::SerializerVersion, 4); fp.writel(SNES::Info::SerializerVersion, 4);

View File

@ -167,16 +167,16 @@ void Utility::cartridgeUnloaded() {
mainWindow.synchronize(); mainWindow.synchronize();
} }
SNES::Cartridge::Slot Utility::stateSlot() { SNES::Cartridge::Path Utility::slotPath() {
SNES::Cartridge::Slot slot = SNES::Cartridge::Slot::Base; SNES::Cartridge::Path path = SNES::Cartridge::Path::Base;
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::Bsx) slot = SNES::Cartridge::Slot::Bsx; if(SNES::cartridge.mode() == SNES::Cartridge::Mode::Bsx) path = SNES::Cartridge::Path::Bsx;
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SufamiTurbo) slot = SNES::Cartridge::Slot::SufamiTurboA; if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SufamiTurbo) path = SNES::Cartridge::Path::SufamiTurbo;
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) slot = SNES::Cartridge::Slot::GameBoy; if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) path = SNES::Cartridge::Path::GameBoy;
return slot; return path;
} }
void Utility::saveState(unsigned slot) { void Utility::saveState(unsigned slot) {
string filename = path.load(stateSlot(), "bst", { "-", slot }); string filename = path.load(slotPath(), { "-", slot, ".bst" });
SNES::system.runtosave(); SNES::system.runtosave();
serializer s = SNES::system.serialize(); serializer s = SNES::system.serialize();
file fp; file fp;
@ -190,7 +190,7 @@ void Utility::saveState(unsigned slot) {
} }
void Utility::loadState(unsigned slot) { void Utility::loadState(unsigned slot) {
string filename = path.load(stateSlot(), "bst", { "-", slot }); string filename = path.load(slotPath(), { "-", slot, ".bst" });
file fp; file fp;
if(fp.open(filename, file::mode::read)) { if(fp.open(filename, file::mode::read)) {
unsigned size = fp.size(); unsigned size = fp.size();

View File

@ -15,7 +15,7 @@ struct Utility : property<Utility> {
void cartridgeLoaded(); void cartridgeLoaded();
void cartridgeUnloaded(); void cartridgeUnloaded();
SNES::Cartridge::Slot stateSlot(); SNES::Cartridge::Path slotPath();
void saveState(unsigned slot); void saveState(unsigned slot);
void loadState(unsigned slot); void loadState(unsigned slot);