Update to v068r21 release.

byuu says:

Changelog:
- adds synchronize video
- adds synchronize audio
- adds mute audio
- adds advanced settings window with driver selection only
- adds the pretty section header thing I started going toward with Qt
- adds a configuration file, saves to bsnes-phoenix.cfg (I don't make
  the .bsnes folder yet)
- the status bar shows [A] for accuracy, [C] for compatibility and [P]
  for carburetor
This commit is contained in:
Tim Allen 2010-09-22 22:51:52 +10:00
parent 4163059b21
commit 9484d1bc92
19 changed files with 297 additions and 55 deletions

View File

@ -78,5 +78,57 @@
#define alwaysinline inline
#endif
//=========================
//file system functionality
//=========================
#if defined(_WIN32)
inline char* realpath(const char *filename, char *resolvedname) {
wchar_t fn[_MAX_PATH] = L"";
_wfullpath(fn, nall::utf16_t(filename), _MAX_PATH);
strcpy(resolvedname, nall::utf8_t(fn));
return resolvedname;
}
inline char* userpath(char *path) {
wchar_t fp[_MAX_PATH] = L"";
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp);
strcpy(path, nall::utf8_t(fp));
return path;
}
inline char* getcwd(char *path) {
wchar_t fp[_MAX_PATH] = L"";
_wgetcwd(fp, _MAX_PATH);
strcpy(path, nall::utf8_t(fp));
return path;
}
inline void initialize_arguments(int &argc, char **&argv) {
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
argv = new char*[argc];
for(unsigned i = 0; i < argc; i++) {
argv[i] = new char[_MAX_PATH];
strcpy(argv[i], nall::utf8_t(wargv[i]));
}
}
#else
//realpath() already exists
inline char* userpath(char *path) {
*path = 0;
struct passwd *userinfo = getpwuid(getuid());
if(userinfo) strcpy(path, userinfo->pw_dir);
return path;
}
inline char *getcwd(char *path) {
return getcwd(path, PATH_MAX);
}
inline void initialize_arguments(int &argc, char **&argv) {
}
#endif
#endif

View File

@ -181,7 +181,7 @@ OS::OS() {
gtk_rc_parse_string(
"style \"phoenix-gtk\"\n"
"{\n"
" GtkComboBox::appears-as-list = 0\n"
" GtkComboBox::appears-as-list = 1\n"
" GtkTreeView::vertical-separator = 0\n"
"}\n"
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"

View File

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

View File

@ -14,13 +14,18 @@ using namespace ruby;
using namespace phoenix;
#include "interface.hpp"
#include "config.hpp"
#include "general/general.hpp"
#include "settings/settings.hpp"
#include "utility/utility.hpp"
#include "cartridge/cartridge.hpp"
struct Application {
Font font;
array<Window*> windows;
Font proportionalFont;
Font proportionalFontBold;
Font monospaceFont;
bool quit;
void main(int argc, char **argv);
};
@ -30,10 +35,16 @@ extern Application application;
struct Style {
enum : unsigned {
#if defined(PHOENIX_WINDOWS)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 25,
#elif defined(PHOENIX_GTK)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 22,
#elif defined(PHOENIX_QT)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 22,
#endif
};

24
bsnes/ui-phoenix/config.cpp Executable file
View File

@ -0,0 +1,24 @@
Configuration config;
void Configuration::load() {
configuration::load(string(path.user, "bsnes-phoenix.cfg"));
}
void Configuration::save() {
configuration::save(string(path.user, "bsnes-phoenix.cfg"));
}
void Configuration::create() {
attach(video.driver = "", "video.driver");
attach(video.synchronize = false, "video.synchronize");
attach(video.contrast = 100, "video.contrast");
attach(video.brightness = 100, "video.brightness");
attach(video.gamma = 100, "video.gamma");
attach(video.useGammaRamp = true, "video.useGammaRamp");
attach(audio.driver = "", "audio.driver");
attach(audio.synchronize = true, "audio.synchronize");
attach(audio.mute = false, "audio.mute");
attach(input.driver = "", "input.driver");
}

31
bsnes/ui-phoenix/config.hpp Executable file
View File

@ -0,0 +1,31 @@
struct Configuration : public configuration {
struct Path {
string base;
string user;
} path;
struct Video {
string driver;
bool synchronize;
unsigned contrast;
unsigned brightness;
unsigned gamma;
bool useGammaRamp;
} video;
struct Audio {
string driver;
bool synchronize;
bool mute;
} audio;
struct Input {
string driver;
} input;
void load();
void save();
void create();
};
extern Configuration config;

View File

@ -1,10 +1,10 @@
MainWindow mainWindow;
void MainWindow::create() {
statusFont.create("Sans", 8, Font::Style::Bold);
application.windows.append(this);
Window::create(120, 120, 595, 448, string(SNES::Info::Name, " v", SNES::Info::Version));
setDefaultFont(application.font);
setFont(statusFont);
setDefaultFont(application.proportionalFont);
setFont(application.proportionalFontBold);
setBackgroundColor(0, 0, 0);
system.create(*this, "System");
@ -13,11 +13,20 @@ void MainWindow::create() {
systemQuit.create(system, "Quit");
setMenuVisible(true);
settings.create(*this, "Settings");
settingsSynchronizeVideo.create(settings, "Synchronize Video");
settingsSynchronizeVideo.setChecked(config.video.synchronize);
settingsSynchronizeAudio.create(settings, "Synchronize Audio");
settingsSynchronizeAudio.setChecked(config.audio.synchronize);
settingsMuteAudio.create(settings, "Mute Audio");
settingsMuteAudio.setChecked(config.audio.mute);
settingsSeparator.create(settings);
settingsVideo.create(settings, "Video Settings ...");
settingsAdvanced.create(settings, "Advanced Settings ...");
tools.create(*this, "Tools");
help.create(*this, "Help");
viewport.create(*this, 0, 0, 595, 448);
utility.setStatus("");
setStatusVisible(true);
systemLoadCartridge.onTick = []() {
@ -28,10 +37,28 @@ void MainWindow::create() {
application.quit = true;
};
settingsSynchronizeVideo.onTick = []() {
config.video.synchronize = mainWindow.settingsSynchronizeVideo.checked();
video.set(Video::Synchronize, config.video.synchronize);
};
settingsSynchronizeAudio.onTick = []() {
config.audio.synchronize = mainWindow.settingsSynchronizeAudio.checked();
audio.set(Audio::Synchronize, config.audio.synchronize);
};
settingsMuteAudio.onTick = []() {
config.audio.mute = mainWindow.settingsMuteAudio.checked();
};
settingsVideo.onTick = []() {
videoSettingsWindow.setVisible();
};
settingsAdvanced.onTick = []() {
advancedSettingsWindow.setVisible();
};
onClose = []() {
application.quit = true;
return false;

View File

@ -1,11 +1,15 @@
struct MainWindow : Window {
Font statusFont;
Menu system;
MenuItem systemLoadCartridge;
MenuSeparator systemSeparator;
MenuItem systemQuit;
Menu settings;
MenuCheckItem settingsSynchronizeVideo;
MenuCheckItem settingsSynchronizeAudio;
MenuCheckItem settingsMuteAudio;
MenuSeparator settingsSeparator;
MenuItem settingsVideo;
MenuItem settingsAdvanced;
Menu tools;
Menu help;
Viewport viewport;

View File

@ -9,19 +9,19 @@ const uint8_t Palette::gammaRamp[32] = {
};
uint8_t Palette::contrastAdjust(uint8_t input) {
signed contrast = Palette::contrast - 100;
signed contrast = config.video.contrast - 100;
signed result = input - contrast + (2 * contrast * input + 127) / 255;
return max(0, min(255, result));
}
uint8_t Palette::brightnessAdjust(uint8_t input) {
signed brightness = Palette::brightness - 100;
signed brightness = config.video.brightness - 100;
signed result = input + brightness;
return max(0, min(255, result));
}
uint8_t Palette::gammaAdjust(uint8_t input) {
signed result = (signed)(pow(((double)input / 255.0), (double)gamma / 100.0) * 255.0 + 0.5);
signed result = (signed)(pow(((double)input / 255.0), (double)config.video.gamma / 100.0) * 255.0 + 0.5);
return max(0, min(255, result));
}
@ -35,25 +35,25 @@ void Palette::update() {
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
if(useGammaRamp) {
if(config.video.useGammaRamp) {
r = gammaRamp[r >> 3];
g = gammaRamp[g >> 3];
b = gammaRamp[b >> 3];
}
if(contrast != 100) {
if(config.video.contrast != 100) {
r = contrastAdjust(r);
g = contrastAdjust(g);
b = contrastAdjust(b);
}
if(brightness != 100) {
if(config.video.brightness != 100) {
r = brightnessAdjust(r);
g = brightnessAdjust(g);
b = brightnessAdjust(b);
}
if(gamma != 100) {
if(config.video.gamma != 100) {
r = gammaAdjust(r);
g = gammaAdjust(g);
b = gammaAdjust(b);
@ -63,14 +63,6 @@ void Palette::update() {
}
}
Palette::Palette() {
contrast = 100;
brightness = 100;
gamma = 100;
useGammaRamp = true;
update();
}
void Interface::video_refresh(const uint16_t *data, unsigned width, unsigned height) {
bool interlace = (height >= 240);
bool overscan = (height == 239 || height == 478);
@ -95,13 +87,14 @@ void Interface::video_refresh(const uint16_t *data, unsigned width, unsigned hei
time(&current);
if(current != previous) {
mainWindow.setStatusText(string("FPS: ", frameCounter));
utility.setStatus(string("FPS: ", frameCounter));
frameCounter = 0;
previous = current;
}
}
void Interface::audio_sample(uint16_t left, uint16_t right) {
if(config.audio.mute) left = right = 0;
audio.sample(left, right);
}

View File

@ -1,15 +1,10 @@
struct Palette {
static const uint8_t gammaRamp[32];
uint32_t color[32768];
unsigned contrast;
unsigned brightness;
unsigned gamma;
bool useGammaRamp;
uint8_t contrastAdjust(uint8_t);
uint8_t brightnessAdjust(uint8_t);
uint8_t gammaAdjust(uint8_t);
void update();
Palette();
};
struct Interface : public SNES::Interface {

View File

@ -1,32 +1,44 @@
#include "base.hpp"
#include "interface.cpp"
#include "config.cpp"
Application application;
#if defined(PLATFORM_WIN)
static string VideoDriver = "Direct3D";
static string AudioDriver = "DirectSound";
static string InputDriver = "RawInput";
#elif defined(PLATFORM_X)
static string VideoDriver = "OpenGL";
static string AudioDriver = "ALSA";
static string InputDriver = "SDL";
#endif
void Application::main(int argc, char **argv) {
initialize_arguments(argc, argv);
config.create();
char temp[PATH_MAX];
config.path.base = realpath(argv[0], temp);
config.path.base.transform("\\", "/");
config.path.base = dir(config.path.base);
config.path.user = userpath(temp);
config.path.user.transform("\\", "/");
if(strend(config.path.user, "/") == false) config.path.user.append("/");
config.path.user.append(".bsnes/");
config.load();
config.save();
#if defined(PHOENIX_WINDOWS)
font.create("Tahoma", 8);
proportionalFont.create("Tahoma", 8);
proportionalFontBold.create("Tahoma", 8, Font::Style::Bold);
monospaceFont.create("Courier New", 8);
#else
font.create("Sans", 8);
proportionalFont.create("Sans", 8);
proportionalFontBold.create("Tahoma", 8, Font::Style::Bold);
monospaceFont.create("Liberation Mono", 8);
#endif
palette.update();
mainWindow.create();
videoSettingsWindow.create();
advancedSettingsWindow.create();
mainWindow.setVisible();
while(os.pending()) os.run();
video.driver(VideoDriver);
if(config.video.driver == "") config.video.driver = video.default_driver();
video.driver(config.video.driver);
video.set(Video::Handle, mainWindow.viewport.handle());
video.set(Video::Synchronize, false);
video.set(Video::Synchronize, config.video.synchronize);
video.set(Video::Filter, (unsigned)Video::FilterLinear);
if(video.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize video.");
@ -34,9 +46,10 @@ void Application::main(int argc, char **argv) {
video.init();
}
audio.driver(AudioDriver);
if(config.audio.driver == "") config.audio.driver = audio.default_driver();
audio.driver(config.audio.driver);
audio.set(Audio::Handle, mainWindow.viewport.handle());
audio.set(Audio::Synchronize, false);
audio.set(Audio::Synchronize, config.audio.synchronize);
audio.set(Audio::Frequency, (unsigned)32000);
if(audio.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize audio.");
@ -44,7 +57,8 @@ void Application::main(int argc, char **argv) {
audio.init();
}
input.driver(InputDriver);
if(config.input.driver == "") config.input.driver = video.default_driver();
input.driver(config.input.driver);
input.set(Input::Handle, mainWindow.viewport.handle());
if(input.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize input.");
@ -69,9 +83,10 @@ void Application::main(int argc, char **argv) {
}
cartridge.unload();
mainWindow.setVisible(false);
foreach(window, windows) window->setVisible(false);
while(os.pending()) os.run();
SNES::system.term();
config.save();
video.term();
audio.term();

View File

@ -0,0 +1,64 @@
AdvancedSettingsWindow advancedSettingsWindow;
void AdvancedSettingsWindow::create() {
application.windows.append(this);
Window::create(0, 0, 256, 256, "Advanced Settings");
setDefaultFont(application.proportionalFont);
unsigned x = 5, y = 5;
driverSelectionLabel.create(*this, x, y, 595, Style::LabelHeight, "Driver Selection :."); y += Style::LabelHeight + 5;
driverSelectionLabel.setFont(application.proportionalFontBold);
videoDriverLabel.create(*this, x, y, 45, Style::ComboBoxHeight, "Video:");
videoDriverBox.create (*this, x + 45, y, 150, Style::ComboBoxHeight);
audioDriverLabel.create(*this, x + 200, y, 45, Style::ComboBoxHeight, "Audio:");
audioDriverBox.create (*this, x + 245, y, 150, Style::ComboBoxHeight);
inputDriverLabel.create(*this, x + 400, y, 45, Style::ComboBoxHeight, "Input:");
inputDriverBox.create (*this, x + 445, y, 150, Style::ComboBoxHeight); y += Style::ComboBoxHeight;
setGeometry(0, 0, 605, y + 5);
lstring list;
list.split(";", video.driver_list());
for(unsigned i = 0; i < list.size(); i++) {
videoDriverBox.addItem(list[i]);
if(list[i] == config.video.driver) videoDriverBox.setSelection(i);
}
list.split(";", audio.driver_list());
for(unsigned i = 0; i < list.size(); i++) {
audioDriverBox.addItem(list[i]);
if(list[i] == config.audio.driver) audioDriverBox.setSelection(i);
}
list.split(";", input.driver_list());
for(unsigned i = 0; i < list.size(); i++) {
inputDriverBox.addItem(list[i]);
if(list[i] == config.input.driver) inputDriverBox.setSelection(i);
}
videoDriverBox.onChange = []() {
lstring list;
list.split(";", video.driver_list());
config.video.driver = list[advancedSettingsWindow.videoDriverBox.selection()];
};
audioDriverBox.onChange = []() {
lstring list;
list.split(";", audio.driver_list());
config.audio.driver = list[advancedSettingsWindow.audioDriverBox.selection()];
};
inputDriverBox.onChange = []() {
lstring list;
list.split(";", input.driver_list());
config.input.driver = list[advancedSettingsWindow.inputDriverBox.selection()];
};
onClose = []() {
advancedSettingsWindow.setVisible(false);
return false;
};
}

View File

@ -0,0 +1,13 @@
struct AdvancedSettingsWindow : Window {
Label driverSelectionLabel;
Label videoDriverLabel;
ComboBox videoDriverBox;
Label audioDriverLabel;
ComboBox audioDriverBox;
Label inputDriverLabel;
ComboBox inputDriverBox;
void create();
};
extern AdvancedSettingsWindow advancedSettingsWindow;

View File

@ -1,2 +1,3 @@
#include "../base.hpp"
#include "video.cpp"
#include "advanced.cpp"

View File

@ -1 +1,2 @@
#include "video.hpp"
#include "advanced.hpp"

View File

@ -1,11 +1,15 @@
VideoSettingsWindow videoSettingsWindow;
void VideoSettingsWindow::create() {
application.windows.append(this);
Window::create(0, 0, 256, 256, "Video Settings");
setDefaultFont(application.font);
setDefaultFont(application.proportionalFont);
unsigned x = 5, y = 5;
colorAdjustmentLabel.create(*this, x, y, 430, Style::LabelHeight, "Color Adjustment :."); y += Style::LabelHeight + 5;
colorAdjustmentLabel.setFont(application.proportionalFontBold);
contrastLabel.create (*this, x, y, 80, Style::SliderHeight, "Contrast:");
contrastValue.create (*this, x + 80, y, 50, Style::SliderHeight, "100%");
contrastSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight;
@ -22,10 +26,10 @@ void VideoSettingsWindow::create() {
setGeometry(0, 0, 440, y + 5);
contrastSlider.setPosition(100);
brightnessSlider.setPosition(100);
gammaSlider.setPosition(100);
gammaRampCheck.setChecked();
contrastSlider.setPosition(config.video.contrast);
brightnessSlider.setPosition(config.video.brightness);
gammaSlider.setPosition(config.video.gamma);
gammaRampCheck.setChecked(config.video.useGammaRamp);
contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick =
{ &VideoSettingsWindow::adjust, this };
@ -41,9 +45,9 @@ void VideoSettingsWindow::adjust() {
brightnessValue.setText(string(brightnessSlider.position(), "%"));
gammaValue.setText(string(gammaSlider.position(), "%"));
palette.contrast = contrastSlider.position();
palette.brightness = brightnessSlider.position();
palette.gamma = gammaSlider.position();
palette.useGammaRamp = gammaRampCheck.checked();
config.video.contrast = contrastSlider.position();
config.video.brightness = brightnessSlider.position();
config.video.gamma = gammaSlider.position();
config.video.useGammaRamp = gammaRampCheck.checked();
palette.update();
}

View File

@ -1,4 +1,5 @@
struct VideoSettingsWindow : Window {
Label colorAdjustmentLabel;
Label contrastLabel;
Label contrastValue;
HorizontalSlider contrastSlider;

View File

@ -9,6 +9,11 @@ void Utility::setTitle(const char *text) {
}
}
void Utility::setStatus(const char *text) {
static char profile[] = { '[', SNES::Info::Profile[0], ']', ' ', 0 };
mainWindow.setStatusText(string(profile, text));
}
void Utility::loadCartridgeNormal() {
string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", "/media/sdb1/root/snes_roms");
if(filename != "") {

View File

@ -1,5 +1,6 @@
struct Utility {
void setTitle(const char *text);
void setStatus(const char *text);
void loadCartridgeNormal();
};