mirror of https://github.com/bsnes-emu/bsnes.git
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.
This commit is contained in:
parent
483f9f8f20
commit
bf78e66027
|
@ -20,6 +20,7 @@ struct Intrinsics {
|
||||||
#define COMPILER_VISUALC
|
#define COMPILER_VISUALC
|
||||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualC; }
|
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualC; }
|
||||||
#else
|
#else
|
||||||
|
#warning "unable to detect compiler"
|
||||||
#define COMPILER_UNKNOWN
|
#define COMPILER_UNKNOWN
|
||||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Unknown; }
|
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Unknown; }
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,8 +38,9 @@ struct Intrinsics {
|
||||||
#define PLATFORM_WIN
|
#define PLATFORM_WIN
|
||||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
|
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
|
||||||
#else
|
#else
|
||||||
|
#warning "unable to detect platform"
|
||||||
#define PLATFORM_UNKNOWN
|
#define PLATFORM_UNKNOWN
|
||||||
|
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Unknown; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Endian detection */
|
/* Endian detection */
|
||||||
|
@ -52,9 +54,10 @@ struct Intrinsics {
|
||||||
#define ARCH_MSB
|
#define ARCH_MSB
|
||||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; }
|
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; }
|
||||||
#else
|
#else
|
||||||
|
#warning "unable to detect endian"
|
||||||
#define ENDIAN_UNKNOWN
|
#define ENDIAN_UNKNOWN
|
||||||
#define ARCH_UNKNOWN
|
#define ARCH_UNKNOWN
|
||||||
Intrinsics::Endian Intrinsics::endia() { return Intrinsics::Endian::Unknown; }
|
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,6 +36,13 @@ namespace nall {
|
||||||
buffersize = newsize;
|
buffersize = newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool append(const T& data, Args&&... args) {
|
||||||
|
bool result = append(data);
|
||||||
|
append(std::forward<Args>(args)...);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool append(const T data) {
|
bool append(const T data) {
|
||||||
for(unsigned index = 0; index < buffersize; index++) {
|
for(unsigned index = 0; index < buffersize; index++) {
|
||||||
if(pool[index] == &data) return false;
|
if(pool[index] == &data) return false;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <snes/snes.hpp>
|
#include <snes/snes.hpp>
|
||||||
#include <gameboy/gameboy.hpp>
|
#include <gameboy/gameboy.hpp>
|
||||||
|
|
||||||
|
#include <nall/compositor.hpp>
|
||||||
#include <nall/config.hpp>
|
#include <nall/config.hpp>
|
||||||
#include <nall/directory.hpp>
|
#include <nall/directory.hpp>
|
||||||
#include <nall/dsp.hpp>
|
#include <nall/dsp.hpp>
|
||||||
|
@ -32,6 +33,7 @@ struct Application {
|
||||||
bool quit;
|
bool quit;
|
||||||
bool pause;
|
bool pause;
|
||||||
bool autopause;
|
bool autopause;
|
||||||
|
bool compositionEnable;
|
||||||
|
|
||||||
string basepath;
|
string basepath;
|
||||||
string userpath;
|
string userpath;
|
||||||
|
|
|
@ -19,12 +19,14 @@ Config::Config() {
|
||||||
attach(video.fullScreenMode = 0, "Video::FullScreenMode");
|
attach(video.fullScreenMode = 0, "Video::FullScreenMode");
|
||||||
|
|
||||||
attach(video.startFullScreen = false, "Video::StartFullScreen");
|
attach(video.startFullScreen = false, "Video::StartFullScreen");
|
||||||
|
attach(video.compositionMode = 0, "Video::CompositionMode");
|
||||||
|
|
||||||
attach(audio.driver = "", "Audio::Driver");
|
attach(audio.driver = "", "Audio::Driver");
|
||||||
attach(audio.synchronize = true, "Audio::Synchronize");
|
attach(audio.synchronize = true, "Audio::Synchronize");
|
||||||
attach(audio.mute = false, "Audio::Mute");
|
attach(audio.mute = false, "Audio::Mute");
|
||||||
attach(audio.volume = 100, "Audio::Volume");
|
attach(audio.volume = 100, "Audio::Volume");
|
||||||
attach(audio.latency = 60, "Audio::Latency");
|
attach(audio.latency = 60, "Audio::Latency");
|
||||||
|
attach(audio.resampler = "sinc", "Audio::Resampler");
|
||||||
|
|
||||||
attach(audio.frequency = 48000, "Audio::Frequency::Native");
|
attach(audio.frequency = 48000, "Audio::Frequency::Native");
|
||||||
attach(audio.frequencyNES = 1789772, "Audio::Frequency::NES");
|
attach(audio.frequencyNES = 1789772, "Audio::Frequency::NES");
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct Config : public configuration {
|
||||||
unsigned gamma;
|
unsigned gamma;
|
||||||
|
|
||||||
unsigned fullScreenMode;
|
unsigned fullScreenMode;
|
||||||
|
unsigned compositionMode;
|
||||||
|
|
||||||
bool startFullScreen;
|
bool startFullScreen;
|
||||||
} video;
|
} video;
|
||||||
|
@ -25,6 +26,7 @@ struct Config : public configuration {
|
||||||
bool mute;
|
bool mute;
|
||||||
unsigned volume;
|
unsigned volume;
|
||||||
unsigned latency;
|
unsigned latency;
|
||||||
|
string resampler;
|
||||||
|
|
||||||
unsigned frequency;
|
unsigned frequency;
|
||||||
unsigned frequencyNES;
|
unsigned frequencyNES;
|
||||||
|
|
|
@ -35,9 +35,7 @@ GameBoyController::GameBoyController() {
|
||||||
select.mapping = "KB0::Apostrophe";
|
select.mapping = "KB0::Apostrophe";
|
||||||
start.mapping = "KB0::Return";
|
start.mapping = "KB0::Return";
|
||||||
|
|
||||||
append(up); append(down); append(left); append(right);
|
append(up, down, left, right, b, a, select, start, bTurbo, aTurbo);
|
||||||
append(b); append(a); append(select); append(start);
|
|
||||||
append(bTurbo); append(aTurbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -35,9 +35,7 @@ NesGamepad::NesGamepad() {
|
||||||
select.mapping = "KB0::Apostrophe";
|
select.mapping = "KB0::Apostrophe";
|
||||||
start.mapping = "KB0::Return";
|
start.mapping = "KB0::Return";
|
||||||
|
|
||||||
append(up); append(down); append(left); append(right);
|
append(up, down, left, right, b,a, select, start, bTurbo, aTurbo);
|
||||||
append(b); append(a); append(select); append(start);
|
|
||||||
append(bTurbo); append(aTurbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -58,6 +56,5 @@ NesPort2Input::NesPort2Input() {
|
||||||
|
|
||||||
NesInput::NesInput() {
|
NesInput::NesInput() {
|
||||||
name = "NES";
|
name = "NES";
|
||||||
append(port1);
|
append(port1, port1);
|
||||||
append(port2);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ int16_t SnesGamepad::poll(unsigned n) {
|
||||||
case SNES::Input::JoypadID::A: return a.poll() | aTurbo.poll();
|
case SNES::Input::JoypadID::A: return a.poll() | aTurbo.poll();
|
||||||
case SNES::Input::JoypadID::Y: return y.poll() | yTurbo.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::X: return x.poll() | xTurbo.poll();
|
||||||
case SNES::Input::JoypadID::L: return l.poll();
|
case SNES::Input::JoypadID::L: return l.poll() | lTurbo.poll();
|
||||||
case SNES::Input::JoypadID::R: return r.poll();
|
case SNES::Input::JoypadID::R: return r.poll() | rTurbo.poll();
|
||||||
case SNES::Input::JoypadID::Select: return select.poll();
|
case SNES::Input::JoypadID::Select: return select.poll();
|
||||||
case SNES::Input::JoypadID::Start: return start.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";
|
b.name = "B", a.name = "A", y.name = "Y", x.name = "X";
|
||||||
l.name = "L", r.name = "R", select.name = "Select", start.name = "Start";
|
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";
|
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) {
|
if(defaultBindings) {
|
||||||
up.mapping = "KB0::Up";
|
up.mapping = "KB0::Up";
|
||||||
|
@ -39,10 +40,8 @@ SnesGamepad::SnesGamepad(const string &name, bool defaultBindings) {
|
||||||
start.mapping = "KB0::Return";
|
start.mapping = "KB0::Return";
|
||||||
}
|
}
|
||||||
|
|
||||||
append(up); append(down); append(left); append(right);
|
append(up, down, left, right, b, a, y, x, l, r, select, start);
|
||||||
append(b); append(a); append(y); append(x);
|
append(bTurbo, aTurbo, yTurbo, xTurbo, lTurbo, rTurbo);
|
||||||
append(l); append(r); append(select); append(start);
|
|
||||||
append(bTurbo); append(aTurbo); append(yTurbo); append(xTurbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -70,8 +69,7 @@ SnesMouse::SnesMouse(const string &name, bool defaultBindings) {
|
||||||
right.mapping = "MS0::Button2";
|
right.mapping = "MS0::Button2";
|
||||||
}
|
}
|
||||||
|
|
||||||
append(xaxis); append(yaxis);
|
append(xaxis, yaxis, left, right);
|
||||||
append(left); append(right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -103,8 +101,7 @@ SnesSuperScope::SnesSuperScope(const string &name, bool defaultBindings) {
|
||||||
pause.mapping = "KB0::P";
|
pause.mapping = "KB0::P";
|
||||||
}
|
}
|
||||||
|
|
||||||
append(xaxis); append(yaxis);
|
append(xaxis, yaxis, trigger, cursor, turbo, pause);
|
||||||
append(trigger); append(cursor); append(turbo); append(pause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -132,8 +129,7 @@ SnesJustifier::SnesJustifier(const string &name, bool defaultBindings) {
|
||||||
start.mapping = "MS0::Button2";
|
start.mapping = "MS0::Button2";
|
||||||
}
|
}
|
||||||
|
|
||||||
append(xaxis), append(yaxis);
|
append(xaxis, yaxis, trigger, start);
|
||||||
append(trigger), append(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -184,6 +180,5 @@ justifier2("Justifier - Port 2", false)
|
||||||
|
|
||||||
SnesInput::SnesInput() {
|
SnesInput::SnesInput() {
|
||||||
name = "SNES";
|
name = "SNES";
|
||||||
append(port1);
|
append(port1, port2);
|
||||||
append(port2);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ struct SnesGamepad : TertiaryInput {
|
||||||
DigitalInput b, a, y, x;
|
DigitalInput b, a, y, x;
|
||||||
DigitalInput l, r, select, start;
|
DigitalInput l, r, select, start;
|
||||||
TurboInput bTurbo, aTurbo, yTurbo, xTurbo;
|
TurboInput bTurbo, aTurbo, yTurbo, xTurbo;
|
||||||
|
TurboInput lTurbo, rTurbo;
|
||||||
|
|
||||||
int16_t poll(unsigned n);
|
int16_t poll(unsigned n);
|
||||||
SnesGamepad(const string &name, bool defaultBindings);
|
SnesGamepad(const string &name, bool defaultBindings);
|
||||||
|
|
|
@ -44,7 +44,15 @@ void Interface::setController(unsigned port, unsigned device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::updateDSP() {
|
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);
|
dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0);
|
||||||
|
|
||||||
switch(mode()) {
|
switch(mode()) {
|
||||||
case Mode::NES: return dspaudio.setFrequency(config->audio.frequencyNES);
|
case Mode::NES: return dspaudio.setFrequency(config->audio.frequencyNES);
|
||||||
case Mode::SNES: return dspaudio.setFrequency(config->audio.frequencySNES);
|
case Mode::SNES: return dspaudio.setFrequency(config->audio.frequencySNES);
|
||||||
|
|
|
@ -27,7 +27,7 @@ void Application::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(int argc, char **argv) {
|
Application::Application(int argc, char **argv) {
|
||||||
title = "bsnes v083.08";
|
title = "bsnes v083.09";
|
||||||
|
|
||||||
application = this;
|
application = this;
|
||||||
quit = false;
|
quit = false;
|
||||||
|
@ -56,6 +56,9 @@ Application::Application(int argc, char **argv) {
|
||||||
boldFont = { fontFamily, "8, Bold" };
|
boldFont = { fontFamily, "8, Bold" };
|
||||||
titleFont = { fontFamily, "16, Bold" };
|
titleFont = { fontFamily, "16, Bold" };
|
||||||
|
|
||||||
|
compositionEnable = compositor::enabled();
|
||||||
|
if(config->video.compositionMode == 2) compositor::enable(false);
|
||||||
|
|
||||||
windowManager = new WindowManager;
|
windowManager = new WindowManager;
|
||||||
mainWindow = new MainWindow;
|
mainWindow = new MainWindow;
|
||||||
fileBrowser = new FileBrowser;
|
fileBrowser = new FileBrowser;
|
||||||
|
@ -104,6 +107,7 @@ Application::Application(int argc, char **argv) {
|
||||||
|
|
||||||
interface->unloadCartridge();
|
interface->unloadCartridge();
|
||||||
windowManager->saveGeometry();
|
windowManager->saveGeometry();
|
||||||
|
if(compositionEnable) compositor::enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
Application::~Application() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ AdvancedSettings::AdvancedSettings() {
|
||||||
RadioBox::group(focusPolicy[0], focusPolicy[1], focusPolicy[2]);
|
RadioBox::group(focusPolicy[0], focusPolicy[1], focusPolicy[2]);
|
||||||
focusPolicy[config->input.focusPolicy].setChecked();
|
focusPolicy[config->input.focusPolicy].setChecked();
|
||||||
aboutLabel.setFont(application->boldFont);
|
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;
|
lstring list;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,33 @@ void AudioSlider::setPosition(unsigned position) {
|
||||||
AudioSettings::AudioSettings() {
|
AudioSettings::AudioSettings() {
|
||||||
title.setFont(application->titleFont);
|
title.setFont(application->titleFont);
|
||||||
title.setText("Audio Settings");
|
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.setFont(application->boldFont);
|
||||||
frequencyAdjustmentLabel.setText("Frequency: (lower to reduce audio crackling; raise to reduce video tearing)");
|
frequencyAdjustmentLabel.setText("Frequency: (lower to reduce audio crackling; raise to reduce video tearing)");
|
||||||
|
|
||||||
|
@ -41,39 +68,79 @@ AudioSettings::AudioSettings() {
|
||||||
gameBoy.base = 4194304;
|
gameBoy.base = 4194304;
|
||||||
gameBoy.step = 131;
|
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(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(frequencyAdjustmentLabel, ~0, 0);
|
||||||
append(nes, ~0, 0);
|
append(nes, ~0, 0);
|
||||||
append(snes, ~0, 0);
|
append(snes, ~0, 0);
|
||||||
append(gameBoy, ~0, 0, 5);
|
append(gameBoy, ~0, 0);
|
||||||
append(outputAdjustmentLabel, ~0, 0);
|
|
||||||
append(volume, ~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);
|
nes.setPosition(config->audio.frequencyNES);
|
||||||
snes.setPosition(config->audio.frequencySNES);
|
snes.setPosition(config->audio.frequencySNES);
|
||||||
gameBoy.setPosition(config->audio.frequencyGameBoy);
|
gameBoy.setPosition(config->audio.frequencyGameBoy);
|
||||||
volume.setPosition(config->audio.volume);
|
|
||||||
|
|
||||||
nes.slider.onChange = snes.slider.onChange = gameBoy.slider.onChange =
|
frequencySelection.onChange = latencySelection.onChange = resamplerSelection.onChange =
|
||||||
volume.slider.onChange =
|
volume.slider.onChange = nes.slider.onChange = snes.slider.onChange = gameBoy.slider.onChange =
|
||||||
{ &AudioSettings::synchronize, this };
|
{ &AudioSettings::synchronize, this };
|
||||||
|
|
||||||
synchronize();
|
synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSettings::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.frequencyNES = nes.position();
|
||||||
config->audio.frequencySNES = snes.position();
|
config->audio.frequencySNES = snes.position();
|
||||||
config->audio.frequencyGameBoy = gameBoy.position();
|
config->audio.frequencyGameBoy = gameBoy.position();
|
||||||
config->audio.volume = volume.position();
|
|
||||||
|
|
||||||
nes.value.setText({ nes.position(), "hz" });
|
nes.value.setText({ nes.position(), "hz" });
|
||||||
snes.value.setText({ snes.position(), "hz" });
|
snes.value.setText({ snes.position(), "hz" });
|
||||||
|
|
|
@ -13,12 +13,19 @@ struct AudioSlider : HorizontalLayout {
|
||||||
|
|
||||||
struct AudioSettings : SettingsLayout {
|
struct AudioSettings : SettingsLayout {
|
||||||
Label title;
|
Label title;
|
||||||
|
Label outputLabel;
|
||||||
|
HorizontalLayout outputLayout;
|
||||||
|
Label frequencyLabel;
|
||||||
|
ComboBox frequencySelection;
|
||||||
|
Label latencyLabel;
|
||||||
|
ComboBox latencySelection;
|
||||||
|
Label resamplerLabel;
|
||||||
|
ComboBox resamplerSelection;
|
||||||
|
AudioSlider volume;
|
||||||
Label frequencyAdjustmentLabel;
|
Label frequencyAdjustmentLabel;
|
||||||
AudioSlider nes;
|
AudioSlider nes;
|
||||||
AudioSlider snes;
|
AudioSlider snes;
|
||||||
AudioSlider gameBoy;
|
AudioSlider gameBoy;
|
||||||
Label outputAdjustmentLabel;
|
|
||||||
AudioSlider volume;
|
|
||||||
|
|
||||||
void synchronize();
|
void synchronize();
|
||||||
AudioSettings();
|
AudioSettings();
|
||||||
|
|
|
@ -29,6 +29,12 @@ VideoSettings::VideoSettings() {
|
||||||
fullScreen[1].setText("Scale");
|
fullScreen[1].setText("Scale");
|
||||||
fullScreen[2].setText("Stretch");
|
fullScreen[2].setText("Stretch");
|
||||||
RadioBox::group(fullScreen[0], fullScreen[1], fullScreen[2]);
|
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(title, ~0, 0, 5);
|
||||||
append(colorAdjustment, ~0, 0);
|
append(colorAdjustment, ~0, 0);
|
||||||
|
@ -39,10 +45,15 @@ VideoSettings::VideoSettings() {
|
||||||
append(overscanHorizontal, ~0, 0);
|
append(overscanHorizontal, ~0, 0);
|
||||||
append(overscanVertical, ~0, 0, 5);
|
append(overscanVertical, ~0, 0, 5);
|
||||||
append(fullScreenMode, ~0, 0);
|
append(fullScreenMode, ~0, 0);
|
||||||
append(fullScreenLayout, ~0, 0);
|
append(fullScreenLayout, ~0, 0, 5);
|
||||||
fullScreenLayout.append(fullScreen[0], ~0, 0, 5);
|
fullScreenLayout.append(fullScreen[0], ~0, 0, 5);
|
||||||
fullScreenLayout.append(fullScreen[1], ~0, 0, 5);
|
fullScreenLayout.append(fullScreen[1], ~0, 0, 5);
|
||||||
fullScreenLayout.append(fullScreen[2], ~0, 0);
|
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);
|
brightness.slider.setPosition(config->video.brightness);
|
||||||
contrast.slider.setPosition(config->video.contrast);
|
contrast.slider.setPosition(config->video.contrast);
|
||||||
|
@ -50,13 +61,32 @@ VideoSettings::VideoSettings() {
|
||||||
overscanHorizontal.slider.setPosition(config->video.maskOverscanHorizontal);
|
overscanHorizontal.slider.setPosition(config->video.maskOverscanHorizontal);
|
||||||
overscanVertical.slider.setPosition(config->video.maskOverscanVertical);
|
overscanVertical.slider.setPosition(config->video.maskOverscanVertical);
|
||||||
fullScreen[config->video.fullScreenMode].setChecked();
|
fullScreen[config->video.fullScreenMode].setChecked();
|
||||||
|
compositor[config->video.compositionMode].setChecked();
|
||||||
|
|
||||||
synchronize();
|
synchronize();
|
||||||
|
|
||||||
brightness.slider.onChange = contrast.slider.onChange = gamma.slider.onChange =
|
brightness.slider.onChange = contrast.slider.onChange = gamma.slider.onChange =
|
||||||
overscanHorizontal.slider.onChange = overscanVertical.slider.onChange =
|
overscanHorizontal.slider.onChange = overscanVertical.slider.onChange =
|
||||||
fullScreen[0].onTick = fullScreen[1].onTick = fullScreen[2].onTick =
|
|
||||||
{ &VideoSettings::synchronize, this };
|
{ &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() {
|
void VideoSettings::synchronize() {
|
||||||
|
@ -65,9 +95,9 @@ void VideoSettings::synchronize() {
|
||||||
config->video.gamma = gamma.slider.position();
|
config->video.gamma = gamma.slider.position();
|
||||||
config->video.maskOverscanHorizontal = overscanHorizontal.slider.position();
|
config->video.maskOverscanHorizontal = overscanHorizontal.slider.position();
|
||||||
config->video.maskOverscanVertical = overscanVertical.slider.position();
|
config->video.maskOverscanVertical = overscanVertical.slider.position();
|
||||||
if(fullScreen[0].checked()) config->video.fullScreenMode = 0;
|
if(fullScreen[0].checked()) { config->video.fullScreenMode = 0; }
|
||||||
if(fullScreen[1].checked()) config->video.fullScreenMode = 1;
|
if(fullScreen[1].checked()) { config->video.fullScreenMode = 1; }
|
||||||
if(fullScreen[2].checked()) config->video.fullScreenMode = 2;
|
if(fullScreen[2].checked()) { config->video.fullScreenMode = 2; }
|
||||||
|
|
||||||
brightness.value.setText({ config->video.brightness, "%" });
|
brightness.value.setText({ config->video.brightness, "%" });
|
||||||
contrast.value.setText({ config->video.contrast, "%" });
|
contrast.value.setText({ config->video.contrast, "%" });
|
||||||
|
|
|
@ -18,6 +18,9 @@ struct VideoSettings : SettingsLayout {
|
||||||
Label fullScreenMode;
|
Label fullScreenMode;
|
||||||
HorizontalLayout fullScreenLayout;
|
HorizontalLayout fullScreenLayout;
|
||||||
RadioBox fullScreen[3];
|
RadioBox fullScreen[3];
|
||||||
|
Label compositorLabel;
|
||||||
|
HorizontalLayout compositorLayout;
|
||||||
|
RadioBox compositor[3];
|
||||||
|
|
||||||
void synchronize();
|
void synchronize();
|
||||||
VideoSettings();
|
VideoSettings();
|
||||||
|
|
|
@ -109,6 +109,11 @@ void Utility::toggleFullScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeMainWindow();
|
resizeMainWindow();
|
||||||
|
if(application->compositionEnable) {
|
||||||
|
if(config->video.compositionMode == 1) {
|
||||||
|
compositor::enable(mainWindow->fullScreen() == false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utility::bindVideoFilter() {
|
void Utility::bindVideoFilter() {
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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 {
|
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,
|
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 void initialize() {
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
if(initialized == true) return;
|
if(initialized == true) return;
|
||||||
|
@ -42,16 +51,12 @@ static void initialize() {
|
||||||
yuvTable = new uint32_t[32768];
|
yuvTable = new uint32_t[32768];
|
||||||
|
|
||||||
for(unsigned i = 0; i < 32768; i++) {
|
for(unsigned i = 0; i < 32768; i++) {
|
||||||
uint8_t R = (i >> 0) & 31;
|
uint32_t C = rgb888(i);
|
||||||
uint8_t G = (i >> 5) & 31;
|
|
||||||
uint8_t B = (i >> 10) & 31;
|
|
||||||
|
|
||||||
//bgr555->bgr888
|
double r = (uint8_t)(C >> 16);
|
||||||
double r = (R << 3) | (R >> 2);
|
double g = (uint8_t)(C >> 8);
|
||||||
double g = (G << 3) | (G >> 2);
|
double b = (uint8_t)(C >> 0);
|
||||||
double b = (B << 3) | (B >> 2);
|
|
||||||
|
|
||||||
//bgr888->yuv
|
|
||||||
double y = (r + g + b) * (0.25f * (63.5f / 48.0f));
|
double y = (r + g + b) * (0.25f * (63.5f / 48.0f));
|
||||||
double u = ((r - b) * 0.25f + 128.0f) * (7.5f / 7.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);
|
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(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
initialize();
|
initialize();
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
int prevline = (y == 0 ? 0 : inputPitch);
|
int prevline = (y == 0 ? 0 : inputPitch);
|
||||||
int nextline = (y == height - 1 ? 0 : inputPitch);
|
int nextline = (y == height - 1 ? 0 : inputPitch);
|
||||||
|
@ -168,15 +173,15 @@ dllexport void filter_render(
|
||||||
*out1++ = 0; *out1++ = 0;
|
*out1++ = 0; *out1++ = 0;
|
||||||
|
|
||||||
for(unsigned x = 1; x < width - 1; x++) {
|
for(unsigned x = 1; x < width - 1; x++) {
|
||||||
uint16_t A = *(in - prevline - 1);
|
uint16_t A = rgb555(*(in - prevline - 1));
|
||||||
uint16_t B = *(in - prevline + 0);
|
uint16_t B = rgb555(*(in - prevline + 0));
|
||||||
uint16_t C = *(in - prevline + 1);
|
uint16_t C = rgb555(*(in - prevline + 1));
|
||||||
uint16_t D = *(in - 1);
|
uint16_t D = rgb555(*(in - 1));
|
||||||
uint16_t E = *(in + 0);
|
uint16_t E = rgb555(*(in + 0));
|
||||||
uint16_t F = *(in + 1);
|
uint16_t F = rgb555(*(in + 1));
|
||||||
uint16_t G = *(in + nextline - 1);
|
uint16_t G = rgb555(*(in + nextline - 1));
|
||||||
uint16_t H = *(in + nextline + 0);
|
uint16_t H = rgb555(*(in + nextline + 0));
|
||||||
uint16_t I = *(in + nextline + 1);
|
uint16_t I = rgb555(*(in + nextline + 1));
|
||||||
uint32_t e = yuvTable[E] + diff_offset;
|
uint32_t e = yuvTable[E] + diff_offset;
|
||||||
|
|
||||||
uint8_t pattern;
|
uint8_t pattern;
|
||||||
|
@ -189,10 +194,10 @@ dllexport void filter_render(
|
||||||
pattern |= diff(e, H) << 6;
|
pattern |= diff(e, H) << 6;
|
||||||
pattern |= diff(e, I) << 7;
|
pattern |= diff(e, I) << 7;
|
||||||
|
|
||||||
*(out0 + 0) = blend(hqTable[pattern], E, A, B, D, F, H); pattern = rotate[pattern];
|
*(out0 + 0) = rgb888(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];
|
*(out0 + 1) = rgb888(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 + 1) = rgb888(blend(hqTable[pattern], E, I, H, F, D, B)); pattern = rotate[pattern];
|
||||||
*(out1 + 0) = blend(hqTable[pattern], E, G, D, H, B, F);
|
*(out1 + 0) = rgb888(blend(hqTable[pattern], E, G, D, H, B, F));
|
||||||
|
|
||||||
in++;
|
in++;
|
||||||
out0 += 2;
|
out0 += 2;
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -13,33 +13,33 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
int prevline = (y == 0 ? 0 : inputPitch);
|
int prevline = (y == 0 ? 0 : inputPitch);
|
||||||
int nextline = (y == height - 1 ? 0 : inputPitch);
|
int nextline = (y == height - 1 ? 0 : inputPitch);
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
for(unsigned x = 0; x < width; x++) {
|
||||||
uint16_t A = *(input - prevline);
|
uint32_t A = *(in - prevline);
|
||||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
uint32_t B = (x > 0) ? *(in - 1) : *in;
|
||||||
uint16_t C = *input;
|
uint32_t C = *in;
|
||||||
uint16_t D = (x < width - 1) ? *(input + 1) : *input;
|
uint32_t D = (x < width - 1) ? *(in + 1) : *in;
|
||||||
uint16_t E = *(input++ + nextline);
|
uint32_t E = *(in++ + nextline);
|
||||||
|
|
||||||
if(A != E && B != D) {
|
if(A != E && B != D) {
|
||||||
*out0++ = (A == B ? C + A - ((C ^ A) & 0x0421) >> 1 : C);
|
*out0++ = (A == B ? C + A - ((C ^ A) & 0x010101) >> 1 : C);
|
||||||
*out0++ = (A == D ? C + A - ((C ^ A) & 0x0421) >> 1 : C);
|
*out0++ = (A == D ? C + A - ((C ^ A) & 0x010101) >> 1 : C);
|
||||||
*out1++ = (E == B ? C + E - ((C ^ E) & 0x0421) >> 1 : C);
|
*out1++ = (E == B ? C + E - ((C ^ E) & 0x010101) >> 1 : C);
|
||||||
*out1++ = (E == D ? C + E - ((C ^ E) & 0x0421) >> 1 : C);
|
*out1++ = (E == D ? C + E - ((C ^ E) & 0x010101) >> 1 : C);
|
||||||
} else {
|
} else {
|
||||||
*out0++ = C;
|
*out0++ = C;
|
||||||
*out0++ = C;
|
*out0++ = C;
|
||||||
|
|
|
@ -16,7 +16,6 @@ objects += out/Scanline-Light.filter
|
||||||
objects += out/Scale2x.filter
|
objects += out/Scale2x.filter
|
||||||
objects += out/LQ2x.filter
|
objects += out/LQ2x.filter
|
||||||
objects += out/HQ2x.filter
|
objects += out/HQ2x.filter
|
||||||
objects += out/Overscan.filter
|
|
||||||
objects += out/Phosphor3x.filter
|
objects += out/Phosphor3x.filter
|
||||||
|
|
||||||
compile = $(cpp) $(link) $(flags) -o $@ -shared $<
|
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/Scale2x.filter: Scale2x/Scale2x.cpp Scale2x/*
|
||||||
out/LQ2x.filter: LQ2x/LQ2x.cpp LQ2x/*
|
out/LQ2x.filter: LQ2x/LQ2x.cpp LQ2x/*
|
||||||
out/HQ2x.filter: HQ2x/HQ2x.cpp HQ2x/*
|
out/HQ2x.filter: HQ2x/HQ2x.cpp HQ2x/*
|
||||||
out/Overscan.filter: Overscan/Overscan.cpp Overscan/*
|
|
||||||
out/Phosphor3x.filter: Phosphor3x/Phosphor3x.cpp Phosphor3x/*
|
out/Phosphor3x.filter: Phosphor3x/Phosphor3x.cpp Phosphor3x/*
|
||||||
|
|
||||||
build: $(objects)
|
build: $(objects)
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
#include <nall/platform.hpp>
|
|
||||||
#include <nall/stdint.hpp>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -13,33 +13,45 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 3;
|
uint32_t *out0 = output + y * outputPitch * 3;
|
||||||
uint16_t *out1 = output + y * outputPitch * 3 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 3 + outputPitch;
|
||||||
uint16_t *out2 = output + y * outputPitch * 3 + outputPitch + outputPitch;
|
uint32_t *out2 = output + y * outputPitch * 3 + outputPitch + outputPitch;
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
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);
|
uint8_t Ar = A >> 16, Ag = A >> 8, Ab = A >> 0;
|
||||||
*out1++ = (full & 0x7c00);
|
uint8_t Br = B >> 16, Bg = B >> 8, Bb = B >> 0;
|
||||||
*out2++ = (half & 0x7c00);
|
uint8_t Cr = C >> 16, Cg = C >> 8, Cb = C >> 0;
|
||||||
|
|
||||||
*out0++ = (full & 0x03e0);
|
A = ((Br >> 0) << 16) + ((Bg >> 1) << 8) + ((Ab >> 1) << 0);
|
||||||
*out1++ = (full & 0x03e0);
|
B = ((Br >> 1) << 16) + ((Bg >> 0) << 8) + ((Bb >> 1) << 0);
|
||||||
*out2++ = (half & 0x03e0);
|
C = ((Cr >> 1) << 16) + ((Bg >> 1) << 8) + ((Bb >> 0) << 0);
|
||||||
|
|
||||||
*out0++ = (full & 0x001f);
|
in++;
|
||||||
*out1++ = (full & 0x001f);
|
|
||||||
*out2++ = (half & 0x001f);
|
*out0++ = A;
|
||||||
|
*out1++ = A;
|
||||||
|
*out2++ = (A & 0xf8f8f8) >> 1;
|
||||||
|
|
||||||
|
*out0++ = B;
|
||||||
|
*out1++ = B;
|
||||||
|
*out2++ = (B & 0xf8f8f8) >> 1;
|
||||||
|
|
||||||
|
*out0++ = C;
|
||||||
|
*out1++ = C;
|
||||||
|
*out2++ = (C & 0xf8f8f8) >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -13,20 +13,20 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
for(unsigned x = 0; x < width; x++) {
|
||||||
uint16_t pixel = *in++;
|
uint32_t pixel = *in++;
|
||||||
*out0++ = pixel;
|
*out0++ = pixel;
|
||||||
*out0++ = pixel;
|
*out0++ = pixel;
|
||||||
*out1++ = pixel;
|
*out1++ = pixel;
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -13,27 +13,27 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
int prevline = (y == 0 ? 0 : inputPitch);
|
int prevline = (y == 0 ? 0 : inputPitch);
|
||||||
int nextline = (y == height - 1 ? 0 : inputPitch);
|
int nextline = (y == height - 1 ? 0 : inputPitch);
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
for(unsigned x = 0; x < width; x++) {
|
||||||
uint16_t A = *(input - prevline);
|
uint32_t A = *(in - prevline);
|
||||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
uint32_t B = (x > 0) ? *(in - 1) : *in;
|
||||||
uint16_t C = *input;
|
uint32_t C = *in;
|
||||||
uint16_t D = (x < width - 1) ? *(input + 1) : *input;
|
uint32_t D = (x < width - 1) ? *(in + 1) : *in;
|
||||||
uint16_t E = *(input++ + nextline);
|
uint32_t E = *(in++ + nextline);
|
||||||
|
|
||||||
if(A != E && B != D) {
|
if(A != E && B != D) {
|
||||||
*out0++ = (A == B ? A : C);
|
*out0++ = (A == B ? A : C);
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -12,17 +12,17 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
for(unsigned x = 0; x < width; x++) {
|
||||||
*out0++ = *in++;
|
*out0++ = *in++;
|
||||||
|
|
|
@ -4,7 +4,7 @@ using namespace nall;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void filter_size(unsigned&, unsigned&);
|
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) {
|
dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
|
@ -12,21 +12,21 @@ dllexport void filter_size(unsigned &width, unsigned &height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dllexport void filter_render(
|
dllexport void filter_render(
|
||||||
uint16_t *output, unsigned outputPitch,
|
uint32_t *output, unsigned outputPitch,
|
||||||
const uint16_t *input, unsigned inputPitch,
|
const uint32_t *input, unsigned inputPitch,
|
||||||
unsigned width, unsigned height
|
unsigned width, unsigned height
|
||||||
) {
|
) {
|
||||||
outputPitch >>= 1, inputPitch >>= 1;
|
outputPitch >>= 2, inputPitch >>= 2;
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for(unsigned y = 0; y < height; y++) {
|
for(unsigned y = 0; y < height; y++) {
|
||||||
const uint16_t *in = input + y * inputPitch;
|
const uint32_t *in = input + y * inputPitch;
|
||||||
uint16_t *out0 = output + y * outputPitch * 2;
|
uint32_t *out0 = output + y * outputPitch * 2;
|
||||||
uint16_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
uint32_t *out1 = output + y * outputPitch * 2 + outputPitch;
|
||||||
|
|
||||||
for(unsigned x = 0; x < width; x++) {
|
for(unsigned x = 0; x < width; x++) {
|
||||||
*out0++ = *in;
|
*out0++ = *in;
|
||||||
*out1++ = (*in++ & 0x7bde) >> 1;
|
*out1++ = (*in++ & 0xf8f8f8) >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue