From bf78e660270669813eaedc49c5abbd575b48cef1 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 31 Oct 2011 20:55:48 +1100 Subject: [PATCH] Update to v083r09 release. byuu says: Added frequency, latency, resampler selection to the audio settings panel (I really only wanted it there for resampler selection ... having three options matches the driver selection style though, so whatever.) The linear/hermite sampler will double the framerate when running Game Boy games, and sounds the same. Same framerate and sound quality on SNES. But it will cause buzzing in many NES titles. Also re-added the composition { never, fullscreen, always } modes. I think that option is clutter, but it's just impossible to get good audio+video on Windows 7 without it ... Lastly, HQ2x was ported over, but not very well. I just convert source pixels from RGB888 to RGB555, and output pixels in the opposite direction. Need someone good to port the diff() and blend functions over to RGB888 in a way that's not terribly slow. --- bsnes/nall/intrinsics.hpp | 7 +- bsnes/nall/reference_array.hpp | 7 ++ bsnes/ui/base.hpp | 2 + bsnes/ui/config/config.cpp | 2 + bsnes/ui/config/config.hpp | 2 + bsnes/ui/input/gameboy.cpp | 4 +- bsnes/ui/input/nes.cpp | 7 +- bsnes/ui/input/snes.cpp | 23 +++--- bsnes/ui/input/snes.hpp | 1 + bsnes/ui/interface/interface.cpp | 8 +++ bsnes/ui/main.cpp | 6 +- bsnes/ui/settings/advanced.cpp | 2 +- bsnes/ui/settings/audio.cpp | 97 ++++++++++++++++++++++---- bsnes/ui/settings/audio.hpp | 11 ++- bsnes/ui/settings/video.cpp | 40 +++++++++-- bsnes/ui/settings/video.hpp | 3 + bsnes/ui/utility/utility.cpp | 5 ++ snesfilter/HQ2x/HQ2x.cpp | 61 ++++++++-------- snesfilter/LQ2x/LQ2x.cpp | 32 ++++----- snesfilter/Makefile | 2 - snesfilter/Overscan/Overscan.cpp | 30 -------- snesfilter/Phosphor3x/Phosphor3x.cpp | 48 ++++++++----- snesfilter/Pixellate2x/Pixellate2x.cpp | 16 ++--- snesfilter/Scale2x/Scale2x.cpp | 24 +++---- snesfilter/Scanline/Scanline-Dark.cpp | 14 ++-- snesfilter/Scanline/Scanline-Light.cpp | 16 ++--- 26 files changed, 293 insertions(+), 177 deletions(-) delete mode 100755 snesfilter/Overscan/Overscan.cpp diff --git a/bsnes/nall/intrinsics.hpp b/bsnes/nall/intrinsics.hpp index 45d25eb2..413ef593 100755 --- a/bsnes/nall/intrinsics.hpp +++ b/bsnes/nall/intrinsics.hpp @@ -20,6 +20,7 @@ struct Intrinsics { #define COMPILER_VISUALC Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualC; } #else + #warning "unable to detect compiler" #define COMPILER_UNKNOWN Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Unknown; } #endif @@ -37,8 +38,9 @@ struct Intrinsics { #define PLATFORM_WIN Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; } #else + #warning "unable to detect platform" #define PLATFORM_UNKNOWN - + Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Unknown; } #endif /* Endian detection */ @@ -52,9 +54,10 @@ struct Intrinsics { #define ARCH_MSB Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; } #else + #warning "unable to detect endian" #define ENDIAN_UNKNOWN #define ARCH_UNKNOWN - Intrinsics::Endian Intrinsics::endia() { return Intrinsics::Endian::Unknown; } + Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; } #endif #endif diff --git a/bsnes/nall/reference_array.hpp b/bsnes/nall/reference_array.hpp index b01ae8c0..bf96802d 100755 --- a/bsnes/nall/reference_array.hpp +++ b/bsnes/nall/reference_array.hpp @@ -36,6 +36,13 @@ namespace nall { buffersize = newsize; } + template + bool append(const T& data, Args&&... args) { + bool result = append(data); + append(std::forward(args)...); + return result; + } + bool append(const T data) { for(unsigned index = 0; index < buffersize; index++) { if(pool[index] == &data) return false; diff --git a/bsnes/ui/base.hpp b/bsnes/ui/base.hpp index 52c066d7..bc22c6c6 100755 --- a/bsnes/ui/base.hpp +++ b/bsnes/ui/base.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ struct Application { bool quit; bool pause; bool autopause; + bool compositionEnable; string basepath; string userpath; diff --git a/bsnes/ui/config/config.cpp b/bsnes/ui/config/config.cpp index 546531e3..d8f46b62 100755 --- a/bsnes/ui/config/config.cpp +++ b/bsnes/ui/config/config.cpp @@ -19,12 +19,14 @@ Config::Config() { attach(video.fullScreenMode = 0, "Video::FullScreenMode"); attach(video.startFullScreen = false, "Video::StartFullScreen"); + attach(video.compositionMode = 0, "Video::CompositionMode"); attach(audio.driver = "", "Audio::Driver"); attach(audio.synchronize = true, "Audio::Synchronize"); attach(audio.mute = false, "Audio::Mute"); attach(audio.volume = 100, "Audio::Volume"); attach(audio.latency = 60, "Audio::Latency"); + attach(audio.resampler = "sinc", "Audio::Resampler"); attach(audio.frequency = 48000, "Audio::Frequency::Native"); attach(audio.frequencyNES = 1789772, "Audio::Frequency::NES"); diff --git a/bsnes/ui/config/config.hpp b/bsnes/ui/config/config.hpp index a5fdaf1a..a20041bd 100755 --- a/bsnes/ui/config/config.hpp +++ b/bsnes/ui/config/config.hpp @@ -15,6 +15,7 @@ struct Config : public configuration { unsigned gamma; unsigned fullScreenMode; + unsigned compositionMode; bool startFullScreen; } video; @@ -25,6 +26,7 @@ struct Config : public configuration { bool mute; unsigned volume; unsigned latency; + string resampler; unsigned frequency; unsigned frequencyNES; diff --git a/bsnes/ui/input/gameboy.cpp b/bsnes/ui/input/gameboy.cpp index 5b5f7357..c8b9bbe2 100755 --- a/bsnes/ui/input/gameboy.cpp +++ b/bsnes/ui/input/gameboy.cpp @@ -35,9 +35,7 @@ GameBoyController::GameBoyController() { select.mapping = "KB0::Apostrophe"; start.mapping = "KB0::Return"; - append(up); append(down); append(left); append(right); - append(b); append(a); append(select); append(start); - append(bTurbo); append(aTurbo); + append(up, down, left, right, b, a, select, start, bTurbo, aTurbo); } // diff --git a/bsnes/ui/input/nes.cpp b/bsnes/ui/input/nes.cpp index 95f5bbf0..60703a0e 100755 --- a/bsnes/ui/input/nes.cpp +++ b/bsnes/ui/input/nes.cpp @@ -35,9 +35,7 @@ NesGamepad::NesGamepad() { select.mapping = "KB0::Apostrophe"; start.mapping = "KB0::Return"; - append(up); append(down); append(left); append(right); - append(b); append(a); append(select); append(start); - append(bTurbo); append(aTurbo); + append(up, down, left, right, b,a, select, start, bTurbo, aTurbo); } // @@ -58,6 +56,5 @@ NesPort2Input::NesPort2Input() { NesInput::NesInput() { name = "NES"; - append(port1); - append(port2); + append(port1, port1); } diff --git a/bsnes/ui/input/snes.cpp b/bsnes/ui/input/snes.cpp index e2e7ad5d..e08c5606 100755 --- a/bsnes/ui/input/snes.cpp +++ b/bsnes/ui/input/snes.cpp @@ -8,8 +8,8 @@ int16_t SnesGamepad::poll(unsigned n) { case SNES::Input::JoypadID::A: return a.poll() | aTurbo.poll(); case SNES::Input::JoypadID::Y: return y.poll() | yTurbo.poll(); case SNES::Input::JoypadID::X: return x.poll() | xTurbo.poll(); - case SNES::Input::JoypadID::L: return l.poll(); - case SNES::Input::JoypadID::R: return r.poll(); + case SNES::Input::JoypadID::L: return l.poll() | lTurbo.poll(); + case SNES::Input::JoypadID::R: return r.poll() | rTurbo.poll(); case SNES::Input::JoypadID::Select: return select.poll(); case SNES::Input::JoypadID::Start: return start.poll(); } @@ -23,6 +23,7 @@ SnesGamepad::SnesGamepad(const string &name, bool defaultBindings) { b.name = "B", a.name = "A", y.name = "Y", x.name = "X"; l.name = "L", r.name = "R", select.name = "Select", start.name = "Start"; bTurbo.name = "Turbo B", aTurbo.name = "Turbo A", yTurbo.name = "Turbo Y", xTurbo.name = "Turbo X"; + lTurbo.name = "Turbo L", rTurbo.name = "Turbo R"; if(defaultBindings) { up.mapping = "KB0::Up"; @@ -39,10 +40,8 @@ SnesGamepad::SnesGamepad(const string &name, bool defaultBindings) { start.mapping = "KB0::Return"; } - append(up); append(down); append(left); append(right); - append(b); append(a); append(y); append(x); - append(l); append(r); append(select); append(start); - append(bTurbo); append(aTurbo); append(yTurbo); append(xTurbo); + append(up, down, left, right, b, a, y, x, l, r, select, start); + append(bTurbo, aTurbo, yTurbo, xTurbo, lTurbo, rTurbo); } // @@ -70,8 +69,7 @@ SnesMouse::SnesMouse(const string &name, bool defaultBindings) { right.mapping = "MS0::Button2"; } - append(xaxis); append(yaxis); - append(left); append(right); + append(xaxis, yaxis, left, right); } // @@ -103,8 +101,7 @@ SnesSuperScope::SnesSuperScope(const string &name, bool defaultBindings) { pause.mapping = "KB0::P"; } - append(xaxis); append(yaxis); - append(trigger); append(cursor); append(turbo); append(pause); + append(xaxis, yaxis, trigger, cursor, turbo, pause); } // @@ -132,8 +129,7 @@ SnesJustifier::SnesJustifier(const string &name, bool defaultBindings) { start.mapping = "MS0::Button2"; } - append(xaxis), append(yaxis); - append(trigger), append(start); + append(xaxis, yaxis, trigger, start); } // @@ -184,6 +180,5 @@ justifier2("Justifier - Port 2", false) SnesInput::SnesInput() { name = "SNES"; - append(port1); - append(port2); + append(port1, port2); } diff --git a/bsnes/ui/input/snes.hpp b/bsnes/ui/input/snes.hpp index 65925589..a9e343a2 100755 --- a/bsnes/ui/input/snes.hpp +++ b/bsnes/ui/input/snes.hpp @@ -3,6 +3,7 @@ struct SnesGamepad : TertiaryInput { DigitalInput b, a, y, x; DigitalInput l, r, select, start; TurboInput bTurbo, aTurbo, yTurbo, xTurbo; + TurboInput lTurbo, rTurbo; int16_t poll(unsigned n); SnesGamepad(const string &name, bool defaultBindings); diff --git a/bsnes/ui/interface/interface.cpp b/bsnes/ui/interface/interface.cpp index 26b4d134..3c714e97 100755 --- a/bsnes/ui/interface/interface.cpp +++ b/bsnes/ui/interface/interface.cpp @@ -44,7 +44,15 @@ void Interface::setController(unsigned port, unsigned device) { } void Interface::updateDSP() { + audio.set(Audio::Frequency, config->audio.frequency); + audio.set(Audio::Latency, config->audio.latency); + + if(config->audio.resampler == "linear" ) dspaudio.setResampler(DSP::ResampleEngine::Linear); + if(config->audio.resampler == "hermite") dspaudio.setResampler(DSP::ResampleEngine::Hermite); + if(config->audio.resampler == "sinc" ) dspaudio.setResampler(DSP::ResampleEngine::Sinc); + dspaudio.setResamplerFrequency(config->audio.frequency); dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0); + switch(mode()) { case Mode::NES: return dspaudio.setFrequency(config->audio.frequencyNES); case Mode::SNES: return dspaudio.setFrequency(config->audio.frequencySNES); diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index 5966950d..9a7a5c18 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -27,7 +27,7 @@ void Application::run() { } Application::Application(int argc, char **argv) { - title = "bsnes v083.08"; + title = "bsnes v083.09"; application = this; quit = false; @@ -56,6 +56,9 @@ Application::Application(int argc, char **argv) { boldFont = { fontFamily, "8, Bold" }; titleFont = { fontFamily, "16, Bold" }; + compositionEnable = compositor::enabled(); + if(config->video.compositionMode == 2) compositor::enable(false); + windowManager = new WindowManager; mainWindow = new MainWindow; fileBrowser = new FileBrowser; @@ -104,6 +107,7 @@ Application::Application(int argc, char **argv) { interface->unloadCartridge(); windowManager->saveGeometry(); + if(compositionEnable) compositor::enable(true); } Application::~Application() { diff --git a/bsnes/ui/settings/advanced.cpp b/bsnes/ui/settings/advanced.cpp index 83d8ae05..f5b8e237 100755 --- a/bsnes/ui/settings/advanced.cpp +++ b/bsnes/ui/settings/advanced.cpp @@ -16,7 +16,7 @@ AdvancedSettings::AdvancedSettings() { RadioBox::group(focusPolicy[0], focusPolicy[1], focusPolicy[2]); focusPolicy[config->input.focusPolicy].setChecked(); aboutLabel.setFont(application->boldFont); - aboutLabel.setText("bsnes author: byuu license: GPLv3 website: http://byuu.org/"); + aboutLabel.setText("bsnes author: byuu license: GPLv3 website: byuu.org"); lstring list; diff --git a/bsnes/ui/settings/audio.cpp b/bsnes/ui/settings/audio.cpp index f934c5ea..e9b3baa1 100755 --- a/bsnes/ui/settings/audio.cpp +++ b/bsnes/ui/settings/audio.cpp @@ -23,6 +23,33 @@ void AudioSlider::setPosition(unsigned position) { AudioSettings::AudioSettings() { title.setFont(application->titleFont); title.setText("Audio Settings"); + + outputLabel.setFont(application->boldFont); + outputLabel.setText("Output settings:"); + + frequencyLabel.setText("Frequency:"); + frequencySelection.append("32000hz"); + frequencySelection.append("44100hz"); + frequencySelection.append("48000hz"); + frequencySelection.append("96000hz"); + + latencyLabel.setText("Latency:"); + latencySelection.append( "40ms"); + latencySelection.append( "60ms"); + latencySelection.append( "80ms"); + latencySelection.append("100ms"); + latencySelection.append("120ms"); + + resamplerLabel.setText("Resampler:"); + resamplerSelection.append("Linear"); + resamplerSelection.append("Hermite"); + resamplerSelection.append("Sinc"); + + volume.name.setText("Volume:"); + volume.slider.setLength(201); + volume.base = 100; + volume.step = 1; + frequencyAdjustmentLabel.setFont(application->boldFont); frequencyAdjustmentLabel.setText("Frequency: (lower to reduce audio crackling; raise to reduce video tearing)"); @@ -41,39 +68,79 @@ AudioSettings::AudioSettings() { gameBoy.base = 4194304; gameBoy.step = 131; - outputAdjustmentLabel.setFont(application->boldFont); - outputAdjustmentLabel.setText("Output:"); - - volume.name.setText("Volume:"); - volume.slider.setLength(201); - volume.base = 100; - volume.step = 1; - append(title, ~0, 0, 5); + append(outputLabel, ~0, 0); + append(outputLayout, ~0, 0, 5); + outputLayout.append(frequencyLabel, 0, 0, 5); + outputLayout.append(frequencySelection, ~0, 0, 5); + outputLayout.append(latencyLabel, 0, 0, 5); + outputLayout.append(latencySelection, ~0, 0, 5); + outputLayout.append(resamplerLabel, 0, 0, 5); + outputLayout.append(resamplerSelection, ~0, 0); + append(volume, ~0, 0, 5); append(frequencyAdjustmentLabel, ~0, 0); append(nes, ~0, 0); append(snes, ~0, 0); - append(gameBoy, ~0, 0, 5); - append(outputAdjustmentLabel, ~0, 0); - append(volume, ~0, 0); + append(gameBoy, ~0, 0); + + frequencySelection.setSelection( + config->audio.frequency == 32000 ? 0 : + config->audio.frequency == 44100 ? 1 : + config->audio.frequency == 48000 ? 2 : + config->audio.frequency == 96000 ? 3 : 0 + ); + + latencySelection.setSelection( + config->audio.latency == 40 ? 0 : + config->audio.latency == 60 ? 1 : + config->audio.latency == 80 ? 2 : + config->audio.latency == 100 ? 3 : + config->audio.latency == 120 ? 4 : 0 + ); + + resamplerSelection.setSelection( + config->audio.resampler == "linear" ? 0 : + config->audio.resampler == "hermite" ? 1 : + config->audio.resampler == "sinc" ? 2 : 0 + ); + + volume.setPosition(config->audio.volume); nes.setPosition(config->audio.frequencyNES); snes.setPosition(config->audio.frequencySNES); gameBoy.setPosition(config->audio.frequencyGameBoy); - volume.setPosition(config->audio.volume); - nes.slider.onChange = snes.slider.onChange = gameBoy.slider.onChange = - volume.slider.onChange = + frequencySelection.onChange = latencySelection.onChange = resamplerSelection.onChange = + volume.slider.onChange = nes.slider.onChange = snes.slider.onChange = gameBoy.slider.onChange = { &AudioSettings::synchronize, this }; synchronize(); } void AudioSettings::synchronize() { + config->audio.frequency = + frequencySelection.selection() == 0 ? 32000 : + frequencySelection.selection() == 1 ? 44100 : + frequencySelection.selection() == 2 ? 48000 : + frequencySelection.selection() == 3 ? 96000 : 48000; + + config->audio.latency = + latencySelection.selection() == 0 ? 40 : + latencySelection.selection() == 1 ? 60 : + latencySelection.selection() == 2 ? 80 : + latencySelection.selection() == 3 ? 100 : + latencySelection.selection() == 4 ? 120 : 60; + + config->audio.resampler = + resamplerSelection.selection() == 0 ? "linear" : + resamplerSelection.selection() == 1 ? "hermite" : + resamplerSelection.selection() == 2 ? "sinc" : "sinc"; + + config->audio.volume = volume.position(); + config->audio.frequencyNES = nes.position(); config->audio.frequencySNES = snes.position(); config->audio.frequencyGameBoy = gameBoy.position(); - config->audio.volume = volume.position(); nes.value.setText({ nes.position(), "hz" }); snes.value.setText({ snes.position(), "hz" }); diff --git a/bsnes/ui/settings/audio.hpp b/bsnes/ui/settings/audio.hpp index 78abc331..a647d122 100755 --- a/bsnes/ui/settings/audio.hpp +++ b/bsnes/ui/settings/audio.hpp @@ -13,12 +13,19 @@ struct AudioSlider : HorizontalLayout { struct AudioSettings : SettingsLayout { Label title; + Label outputLabel; + HorizontalLayout outputLayout; + Label frequencyLabel; + ComboBox frequencySelection; + Label latencyLabel; + ComboBox latencySelection; + Label resamplerLabel; + ComboBox resamplerSelection; + AudioSlider volume; Label frequencyAdjustmentLabel; AudioSlider nes; AudioSlider snes; AudioSlider gameBoy; - Label outputAdjustmentLabel; - AudioSlider volume; void synchronize(); AudioSettings(); diff --git a/bsnes/ui/settings/video.cpp b/bsnes/ui/settings/video.cpp index cb0a651b..47fd2ed0 100755 --- a/bsnes/ui/settings/video.cpp +++ b/bsnes/ui/settings/video.cpp @@ -29,6 +29,12 @@ VideoSettings::VideoSettings() { fullScreen[1].setText("Scale"); fullScreen[2].setText("Stretch"); RadioBox::group(fullScreen[0], fullScreen[1], fullScreen[2]); + compositorLabel.setText("Disable window compositor:"); + compositorLabel.setFont(application->boldFont); + compositor[0].setText("Never"); + compositor[1].setText("Fullscreen"); + compositor[2].setText("Always"); + RadioBox::group(compositor[0], compositor[1], compositor[2]); append(title, ~0, 0, 5); append(colorAdjustment, ~0, 0); @@ -39,10 +45,15 @@ VideoSettings::VideoSettings() { append(overscanHorizontal, ~0, 0); append(overscanVertical, ~0, 0, 5); append(fullScreenMode, ~0, 0); - append(fullScreenLayout, ~0, 0); + append(fullScreenLayout, ~0, 0, 5); fullScreenLayout.append(fullScreen[0], ~0, 0, 5); fullScreenLayout.append(fullScreen[1], ~0, 0, 5); fullScreenLayout.append(fullScreen[2], ~0, 0); + append(compositorLabel, ~0, 0); + append(compositorLayout, ~0, 0); + compositorLayout.append(compositor[0], ~0, 0, 5); + compositorLayout.append(compositor[1], ~0, 0, 5); + compositorLayout.append(compositor[2], ~0, 0); brightness.slider.setPosition(config->video.brightness); contrast.slider.setPosition(config->video.contrast); @@ -50,13 +61,32 @@ VideoSettings::VideoSettings() { overscanHorizontal.slider.setPosition(config->video.maskOverscanHorizontal); overscanVertical.slider.setPosition(config->video.maskOverscanVertical); fullScreen[config->video.fullScreenMode].setChecked(); + compositor[config->video.compositionMode].setChecked(); synchronize(); brightness.slider.onChange = contrast.slider.onChange = gamma.slider.onChange = overscanHorizontal.slider.onChange = overscanVertical.slider.onChange = - fullScreen[0].onTick = fullScreen[1].onTick = fullScreen[2].onTick = { &VideoSettings::synchronize, this }; + + fullScreen[0].onTick = [&] { config->video.fullScreenMode = 0; }; + fullScreen[1].onTick = [&] { config->video.fullScreenMode = 1; }; + fullScreen[2].onTick = [&] { config->video.fullScreenMode = 2; }; + + compositor[0].onTick = [&] { + config->video.compositionMode = 0; + compositor::enable(application->compositionEnable); + }; + + compositor[1].onTick = [&] { + config->video.compositionMode = 1; + compositor::enable(application->compositionEnable && mainWindow->fullScreen() == false); + }; + + compositor[2].onTick = [&] { + config->video.compositionMode = 2; + compositor::enable(false); + }; } void VideoSettings::synchronize() { @@ -65,9 +95,9 @@ void VideoSettings::synchronize() { config->video.gamma = gamma.slider.position(); config->video.maskOverscanHorizontal = overscanHorizontal.slider.position(); config->video.maskOverscanVertical = overscanVertical.slider.position(); - if(fullScreen[0].checked()) config->video.fullScreenMode = 0; - if(fullScreen[1].checked()) config->video.fullScreenMode = 1; - if(fullScreen[2].checked()) config->video.fullScreenMode = 2; + if(fullScreen[0].checked()) { config->video.fullScreenMode = 0; } + if(fullScreen[1].checked()) { config->video.fullScreenMode = 1; } + if(fullScreen[2].checked()) { config->video.fullScreenMode = 2; } brightness.value.setText({ config->video.brightness, "%" }); contrast.value.setText({ config->video.contrast, "%" }); diff --git a/bsnes/ui/settings/video.hpp b/bsnes/ui/settings/video.hpp index 111df450..ce5866d1 100755 --- a/bsnes/ui/settings/video.hpp +++ b/bsnes/ui/settings/video.hpp @@ -18,6 +18,9 @@ struct VideoSettings : SettingsLayout { Label fullScreenMode; HorizontalLayout fullScreenLayout; RadioBox fullScreen[3]; + Label compositorLabel; + HorizontalLayout compositorLayout; + RadioBox compositor[3]; void synchronize(); VideoSettings(); diff --git a/bsnes/ui/utility/utility.cpp b/bsnes/ui/utility/utility.cpp index 9f5c3b38..cfcd5f31 100755 --- a/bsnes/ui/utility/utility.cpp +++ b/bsnes/ui/utility/utility.cpp @@ -109,6 +109,11 @@ void Utility::toggleFullScreen() { } resizeMainWindow(); + if(application->compositionEnable) { + if(config->video.compositionMode == 1) { + compositor::enable(mainWindow->fullScreen() == false); + } + } } void Utility::bindVideoFilter() { diff --git a/snesfilter/HQ2x/HQ2x.cpp b/snesfilter/HQ2x/HQ2x.cpp index 89aa1e70..46f88c15 100755 --- a/snesfilter/HQ2x/HQ2x.cpp +++ b/snesfilter/HQ2x/HQ2x.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; enum { @@ -34,6 +34,15 @@ const uint8_t hqTable[256] = { 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 1, 12, 5, 3, 1, 14, }; +static uint16_t rgb555(uint32_t C) { + return ((C >> 9) & 0x7c00) + ((C >> 6) & 0x03e0) + ((C >> 3) & 0x001f); +} + +static uint32_t rgb888(uint16_t C) { + return ((C & 0x7c00) << 9) + ((C & 0x03e0) << 6) + ((C & 0x001f) << 3) + + ((C & 0x7000) << 4) + ((C & 0x0380) << 1) + ((C & 0x001c) >> 2); +} + static void initialize() { static bool initialized = false; if(initialized == true) return; @@ -42,16 +51,12 @@ static void initialize() { yuvTable = new uint32_t[32768]; for(unsigned i = 0; i < 32768; i++) { - uint8_t R = (i >> 0) & 31; - uint8_t G = (i >> 5) & 31; - uint8_t B = (i >> 10) & 31; + uint32_t C = rgb888(i); - //bgr555->bgr888 - double r = (R << 3) | (R >> 2); - double g = (G << 3) | (G >> 2); - double b = (B << 3) | (B >> 2); + double r = (uint8_t)(C >> 16); + double g = (uint8_t)(C >> 8); + double b = (uint8_t)(C >> 0); - //bgr888->yuv double y = (r + g + b) * (0.25f * (63.5f / 48.0f)); double u = ((r - b) * 0.25f + 128.0f) * (7.5f / 7.0f); double v = ((g * 2.0f - r - b) * 0.125f + 128.0f) * (7.5f / 6.0f); @@ -147,18 +152,18 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { initialize(); - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; int prevline = (y == 0 ? 0 : inputPitch); int nextline = (y == height - 1 ? 0 : inputPitch); @@ -168,15 +173,15 @@ dllexport void filter_render( *out1++ = 0; *out1++ = 0; for(unsigned x = 1; x < width - 1; x++) { - uint16_t A = *(in - prevline - 1); - uint16_t B = *(in - prevline + 0); - uint16_t C = *(in - prevline + 1); - uint16_t D = *(in - 1); - uint16_t E = *(in + 0); - uint16_t F = *(in + 1); - uint16_t G = *(in + nextline - 1); - uint16_t H = *(in + nextline + 0); - uint16_t I = *(in + nextline + 1); + uint16_t A = rgb555(*(in - prevline - 1)); + uint16_t B = rgb555(*(in - prevline + 0)); + uint16_t C = rgb555(*(in - prevline + 1)); + uint16_t D = rgb555(*(in - 1)); + uint16_t E = rgb555(*(in + 0)); + uint16_t F = rgb555(*(in + 1)); + uint16_t G = rgb555(*(in + nextline - 1)); + uint16_t H = rgb555(*(in + nextline + 0)); + uint16_t I = rgb555(*(in + nextline + 1)); uint32_t e = yuvTable[E] + diff_offset; uint8_t pattern; @@ -189,10 +194,10 @@ dllexport void filter_render( pattern |= diff(e, H) << 6; pattern |= diff(e, I) << 7; - *(out0 + 0) = blend(hqTable[pattern], E, A, B, D, F, H); pattern = rotate[pattern]; - *(out0 + 1) = blend(hqTable[pattern], E, C, F, B, H, D); pattern = rotate[pattern]; - *(out1 + 1) = blend(hqTable[pattern], E, I, H, F, D, B); pattern = rotate[pattern]; - *(out1 + 0) = blend(hqTable[pattern], E, G, D, H, B, F); + *(out0 + 0) = rgb888(blend(hqTable[pattern], E, A, B, D, F, H)); pattern = rotate[pattern]; + *(out0 + 1) = rgb888(blend(hqTable[pattern], E, C, F, B, H, D)); pattern = rotate[pattern]; + *(out1 + 1) = rgb888(blend(hqTable[pattern], E, I, H, F, D, B)); pattern = rotate[pattern]; + *(out1 + 0) = rgb888(blend(hqTable[pattern], E, G, D, H, B, F)); in++; out0 += 2; diff --git a/snesfilter/LQ2x/LQ2x.cpp b/snesfilter/LQ2x/LQ2x.cpp index 9da5f593..f5696266 100755 --- a/snesfilter/LQ2x/LQ2x.cpp +++ b/snesfilter/LQ2x/LQ2x.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -13,33 +13,33 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; int prevline = (y == 0 ? 0 : inputPitch); int nextline = (y == height - 1 ? 0 : inputPitch); for(unsigned x = 0; x < width; x++) { - uint16_t A = *(input - prevline); - uint16_t B = (x > 0) ? *(input - 1) : *input; - uint16_t C = *input; - uint16_t D = (x < width - 1) ? *(input + 1) : *input; - uint16_t E = *(input++ + nextline); + uint32_t A = *(in - prevline); + uint32_t B = (x > 0) ? *(in - 1) : *in; + uint32_t C = *in; + uint32_t D = (x < width - 1) ? *(in + 1) : *in; + uint32_t E = *(in++ + nextline); if(A != E && B != D) { - *out0++ = (A == B ? C + A - ((C ^ A) & 0x0421) >> 1 : C); - *out0++ = (A == D ? C + A - ((C ^ A) & 0x0421) >> 1 : C); - *out1++ = (E == B ? C + E - ((C ^ E) & 0x0421) >> 1 : C); - *out1++ = (E == D ? C + E - ((C ^ E) & 0x0421) >> 1 : C); + *out0++ = (A == B ? C + A - ((C ^ A) & 0x010101) >> 1 : C); + *out0++ = (A == D ? C + A - ((C ^ A) & 0x010101) >> 1 : C); + *out1++ = (E == B ? C + E - ((C ^ E) & 0x010101) >> 1 : C); + *out1++ = (E == D ? C + E - ((C ^ E) & 0x010101) >> 1 : C); } else { *out0++ = C; *out0++ = C; diff --git a/snesfilter/Makefile b/snesfilter/Makefile index 6b632820..1a29918a 100755 --- a/snesfilter/Makefile +++ b/snesfilter/Makefile @@ -16,7 +16,6 @@ objects += out/Scanline-Light.filter objects += out/Scale2x.filter objects += out/LQ2x.filter objects += out/HQ2x.filter -objects += out/Overscan.filter objects += out/Phosphor3x.filter compile = $(cpp) $(link) $(flags) -o $@ -shared $< @@ -31,7 +30,6 @@ out/Scanline-Light.filter: Scanline/Scanline-Light.cpp Scanline/* out/Scale2x.filter: Scale2x/Scale2x.cpp Scale2x/* out/LQ2x.filter: LQ2x/LQ2x.cpp LQ2x/* out/HQ2x.filter: HQ2x/HQ2x.cpp HQ2x/* -out/Overscan.filter: Overscan/Overscan.cpp Overscan/* out/Phosphor3x.filter: Phosphor3x/Phosphor3x.cpp Phosphor3x/* build: $(objects) diff --git a/snesfilter/Overscan/Overscan.cpp b/snesfilter/Overscan/Overscan.cpp deleted file mode 100755 index 05500964..00000000 --- a/snesfilter/Overscan/Overscan.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -using namespace nall; - -extern "C" { - void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); -}; - -dllexport void filter_size(unsigned &width, unsigned &height) { -} - -dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, - unsigned width, unsigned height -) { - outputPitch >>= 1, inputPitch >>= 1; - - #pragma omp parallel for - for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out = output + y * outputPitch; - for(unsigned x = 0; x < width; x++) { - uint16_t pixel = *in++; - if(x < 8 || x >= width - 8 || y < 8 || y >= height - 8) pixel = 0; - *out++ = pixel; - } - } -} diff --git a/snesfilter/Phosphor3x/Phosphor3x.cpp b/snesfilter/Phosphor3x/Phosphor3x.cpp index 4ed1e313..817fc9be 100755 --- a/snesfilter/Phosphor3x/Phosphor3x.cpp +++ b/snesfilter/Phosphor3x/Phosphor3x.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -13,33 +13,45 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 3; - uint16_t *out1 = output + y * outputPitch * 3 + outputPitch; - uint16_t *out2 = output + y * outputPitch * 3 + outputPitch + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 3; + uint32_t *out1 = output + y * outputPitch * 3 + outputPitch; + uint32_t *out2 = output + y * outputPitch * 3 + outputPitch + outputPitch; for(unsigned x = 0; x < width; x++) { - uint16_t full = *in++, half = (full >> 1) & 0x3def; + uint32_t A = (x == 0 ? 0 : *(in - 1)); + uint32_t B = *in; + uint32_t C = (x == width - 1 ? 0 : *(in + 1)); - *out0++ = (full & 0x7c00); - *out1++ = (full & 0x7c00); - *out2++ = (half & 0x7c00); + uint8_t Ar = A >> 16, Ag = A >> 8, Ab = A >> 0; + uint8_t Br = B >> 16, Bg = B >> 8, Bb = B >> 0; + uint8_t Cr = C >> 16, Cg = C >> 8, Cb = C >> 0; - *out0++ = (full & 0x03e0); - *out1++ = (full & 0x03e0); - *out2++ = (half & 0x03e0); + A = ((Br >> 0) << 16) + ((Bg >> 1) << 8) + ((Ab >> 1) << 0); + B = ((Br >> 1) << 16) + ((Bg >> 0) << 8) + ((Bb >> 1) << 0); + C = ((Cr >> 1) << 16) + ((Bg >> 1) << 8) + ((Bb >> 0) << 0); - *out0++ = (full & 0x001f); - *out1++ = (full & 0x001f); - *out2++ = (half & 0x001f); + in++; + + *out0++ = A; + *out1++ = A; + *out2++ = (A & 0xf8f8f8) >> 1; + + *out0++ = B; + *out1++ = B; + *out2++ = (B & 0xf8f8f8) >> 1; + + *out0++ = C; + *out1++ = C; + *out2++ = (C & 0xf8f8f8) >> 1; } } } diff --git a/snesfilter/Pixellate2x/Pixellate2x.cpp b/snesfilter/Pixellate2x/Pixellate2x.cpp index c15a3b67..0376d191 100755 --- a/snesfilter/Pixellate2x/Pixellate2x.cpp +++ b/snesfilter/Pixellate2x/Pixellate2x.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -13,20 +13,20 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; for(unsigned x = 0; x < width; x++) { - uint16_t pixel = *in++; + uint32_t pixel = *in++; *out0++ = pixel; *out0++ = pixel; *out1++ = pixel; diff --git a/snesfilter/Scale2x/Scale2x.cpp b/snesfilter/Scale2x/Scale2x.cpp index a98f08d4..6e5025dc 100755 --- a/snesfilter/Scale2x/Scale2x.cpp +++ b/snesfilter/Scale2x/Scale2x.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -13,27 +13,27 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; int prevline = (y == 0 ? 0 : inputPitch); int nextline = (y == height - 1 ? 0 : inputPitch); for(unsigned x = 0; x < width; x++) { - uint16_t A = *(input - prevline); - uint16_t B = (x > 0) ? *(input - 1) : *input; - uint16_t C = *input; - uint16_t D = (x < width - 1) ? *(input + 1) : *input; - uint16_t E = *(input++ + nextline); + uint32_t A = *(in - prevline); + uint32_t B = (x > 0) ? *(in - 1) : *in; + uint32_t C = *in; + uint32_t D = (x < width - 1) ? *(in + 1) : *in; + uint32_t E = *(in++ + nextline); if(A != E && B != D) { *out0++ = (A == B ? A : C); diff --git a/snesfilter/Scanline/Scanline-Dark.cpp b/snesfilter/Scanline/Scanline-Dark.cpp index 68c1f72c..8ff69e40 100755 --- a/snesfilter/Scanline/Scanline-Dark.cpp +++ b/snesfilter/Scanline/Scanline-Dark.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -12,17 +12,17 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; for(unsigned x = 0; x < width; x++) { *out0++ = *in++; diff --git a/snesfilter/Scanline/Scanline-Light.cpp b/snesfilter/Scanline/Scanline-Light.cpp index 6662a9c7..f38b8ef9 100755 --- a/snesfilter/Scanline/Scanline-Light.cpp +++ b/snesfilter/Scanline/Scanline-Light.cpp @@ -4,7 +4,7 @@ using namespace nall; extern "C" { void filter_size(unsigned&, unsigned&); - void filter_render(uint16_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned); + void filter_render(uint32_t*, unsigned, const uint32_t*, unsigned, unsigned, unsigned); }; dllexport void filter_size(unsigned &width, unsigned &height) { @@ -12,21 +12,21 @@ dllexport void filter_size(unsigned &width, unsigned &height) { } dllexport void filter_render( - uint16_t *output, unsigned outputPitch, - const uint16_t *input, unsigned inputPitch, + uint32_t *output, unsigned outputPitch, + const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height ) { - outputPitch >>= 1, inputPitch >>= 1; + outputPitch >>= 2, inputPitch >>= 2; #pragma omp parallel for for(unsigned y = 0; y < height; y++) { - const uint16_t *in = input + y * inputPitch; - uint16_t *out0 = output + y * outputPitch * 2; - uint16_t *out1 = output + y * outputPitch * 2 + outputPitch; + const uint32_t *in = input + y * inputPitch; + uint32_t *out0 = output + y * outputPitch * 2; + uint32_t *out1 = output + y * outputPitch * 2 + outputPitch; for(unsigned x = 0; x < width; x++) { *out0++ = *in; - *out1++ = (*in++ & 0x7bde) >> 1; + *out1++ = (*in++ & 0xf8f8f8) >> 1; } } }