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 #define alwaysinline inline
#endif #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 #endif

View File

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

View File

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

View File

@ -14,13 +14,18 @@ using namespace ruby;
using namespace phoenix; using namespace phoenix;
#include "interface.hpp" #include "interface.hpp"
#include "config.hpp"
#include "general/general.hpp" #include "general/general.hpp"
#include "settings/settings.hpp" #include "settings/settings.hpp"
#include "utility/utility.hpp" #include "utility/utility.hpp"
#include "cartridge/cartridge.hpp" #include "cartridge/cartridge.hpp"
struct Application { struct Application {
Font font; array<Window*> windows;
Font proportionalFont;
Font proportionalFontBold;
Font monospaceFont;
bool quit; bool quit;
void main(int argc, char **argv); void main(int argc, char **argv);
}; };
@ -30,10 +35,16 @@ extern Application application;
struct Style { struct Style {
enum : unsigned { enum : unsigned {
#if defined(PHOENIX_WINDOWS) #if defined(PHOENIX_WINDOWS)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 25, SliderHeight = 25,
#elif defined(PHOENIX_GTK) #elif defined(PHOENIX_GTK)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 22, SliderHeight = 22,
#elif defined(PHOENIX_QT) #elif defined(PHOENIX_QT)
ComboBoxHeight = 22,
LabelHeight = 15,
SliderHeight = 22, SliderHeight = 22,
#endif #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; MainWindow mainWindow;
void MainWindow::create() { 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)); Window::create(120, 120, 595, 448, string(SNES::Info::Name, " v", SNES::Info::Version));
setDefaultFont(application.font); setDefaultFont(application.proportionalFont);
setFont(statusFont); setFont(application.proportionalFontBold);
setBackgroundColor(0, 0, 0); setBackgroundColor(0, 0, 0);
system.create(*this, "System"); system.create(*this, "System");
@ -13,11 +13,20 @@ void MainWindow::create() {
systemQuit.create(system, "Quit"); systemQuit.create(system, "Quit");
setMenuVisible(true); setMenuVisible(true);
settings.create(*this, "Settings"); 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 ..."); settingsVideo.create(settings, "Video Settings ...");
settingsAdvanced.create(settings, "Advanced Settings ...");
tools.create(*this, "Tools"); tools.create(*this, "Tools");
help.create(*this, "Help"); help.create(*this, "Help");
viewport.create(*this, 0, 0, 595, 448); viewport.create(*this, 0, 0, 595, 448);
utility.setStatus("");
setStatusVisible(true); setStatusVisible(true);
systemLoadCartridge.onTick = []() { systemLoadCartridge.onTick = []() {
@ -28,10 +37,28 @@ void MainWindow::create() {
application.quit = true; 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 = []() { settingsVideo.onTick = []() {
videoSettingsWindow.setVisible(); videoSettingsWindow.setVisible();
}; };
settingsAdvanced.onTick = []() {
advancedSettingsWindow.setVisible();
};
onClose = []() { onClose = []() {
application.quit = true; application.quit = true;
return false; return false;

View File

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

View File

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

View File

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

View File

@ -1,32 +1,44 @@
#include "base.hpp" #include "base.hpp"
#include "interface.cpp" #include "interface.cpp"
#include "config.cpp"
Application application; 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) { 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) #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 #else
font.create("Sans", 8); proportionalFont.create("Sans", 8);
proportionalFontBold.create("Tahoma", 8, Font::Style::Bold);
monospaceFont.create("Liberation Mono", 8);
#endif #endif
palette.update();
mainWindow.create(); mainWindow.create();
videoSettingsWindow.create(); videoSettingsWindow.create();
advancedSettingsWindow.create();
mainWindow.setVisible(); mainWindow.setVisible();
while(os.pending()) os.run(); 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::Handle, mainWindow.viewport.handle());
video.set(Video::Synchronize, false); video.set(Video::Synchronize, config.video.synchronize);
video.set(Video::Filter, (unsigned)Video::FilterLinear); video.set(Video::Filter, (unsigned)Video::FilterLinear);
if(video.init() == false) { if(video.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize video."); MessageWindow::critical(mainWindow, "Failed to initialize video.");
@ -34,9 +46,10 @@ void Application::main(int argc, char **argv) {
video.init(); 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::Handle, mainWindow.viewport.handle());
audio.set(Audio::Synchronize, false); audio.set(Audio::Synchronize, config.audio.synchronize);
audio.set(Audio::Frequency, (unsigned)32000); audio.set(Audio::Frequency, (unsigned)32000);
if(audio.init() == false) { if(audio.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize audio."); MessageWindow::critical(mainWindow, "Failed to initialize audio.");
@ -44,7 +57,8 @@ void Application::main(int argc, char **argv) {
audio.init(); 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()); input.set(Input::Handle, mainWindow.viewport.handle());
if(input.init() == false) { if(input.init() == false) {
MessageWindow::critical(mainWindow, "Failed to initialize input."); MessageWindow::critical(mainWindow, "Failed to initialize input.");
@ -69,9 +83,10 @@ void Application::main(int argc, char **argv) {
} }
cartridge.unload(); cartridge.unload();
mainWindow.setVisible(false); foreach(window, windows) window->setVisible(false);
while(os.pending()) os.run(); while(os.pending()) os.run();
SNES::system.term(); SNES::system.term();
config.save();
video.term(); video.term();
audio.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 "../base.hpp"
#include "video.cpp" #include "video.cpp"
#include "advanced.cpp"

View File

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

View File

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

View File

@ -1,4 +1,5 @@
struct VideoSettingsWindow : Window { struct VideoSettingsWindow : Window {
Label colorAdjustmentLabel;
Label contrastLabel; Label contrastLabel;
Label contrastValue; Label contrastValue;
HorizontalSlider contrastSlider; 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() { void Utility::loadCartridgeNormal() {
string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", "/media/sdb1/root/snes_roms"); string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", "/media/sdb1/root/snes_roms");
if(filename != "") { if(filename != "") {

View File

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