Update to bsnes v035 release.

Changelog:
    - Added video synchronization support at long last [blargg, byuu].
    - Added audio panel to control volume, latency, frequency and SNES input frequency settings.
    - Added driver panel to select APIs to use for video, audio and input.
    - Added crash handler for driver initialization.
    - Xv and SDL video drivers now work with compositing enabled on Linux/Xorg.
    - Improved ALSA audio driver for Linux.
    - Now using a fixed output frequency, along with a 4-tap hermite resampler.
    - Improved header detection; fixes Batman: Revenge of The Joker and a few fan translations.
    - Frameskip will now randomly choose a frame in each set to display; helps with animations.
    - Locales now support meta-data, which allows for unique translations of the same English input.
This commit is contained in:
byuu 2008-08-22 22:28:00 +00:00
parent e2cc164f70
commit 8c591ce44a
18 changed files with 248 additions and 144 deletions

BIN
bsnes.exe

Binary file not shown.

View File

@ -1,5 +1,5 @@
bsnes bsnes
Version: 0.034 Version: 0.035
Author: byuu Author: byuu
======== ========

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.034.06" #define BSNES_VERSION "0.035"
#define BSNES_TITLE "bsnes v" BSNES_VERSION #define BSNES_TITLE "bsnes v" BSNES_VERSION
#define BUSCORE sBus #define BUSCORE sBus

View File

@ -9,16 +9,27 @@ namespace nall {
class dictionary : noncopyable { class dictionary : noncopyable {
public: public:
const char* operator[](const char *input) const { string operator[](const char *input) {
for(unsigned i = 0; i < index_input.size(); i++) { for(unsigned i = 0; i < index_input.size(); i++) {
if(!strcmp(input, index_input[i])) return index_output[i]; if(index_input[i] == input) return index_output[i];
} }
return input; //no match, return input rather than null string
//no match, use input; remove input identifier, if one exists
if(strbegin(input, "{{")) {
int pos = strpos(input, "}}");
if(pos >= 0) {
string temp = substr(input, pos + 2);
return temp;
}
}
return input;
} }
bool import(const char *filename) { bool import(const char *filename) {
string data; string data;
if(fread(data, filename) == false) return false; if(fread(data, filename) == false) return false;
ltrim_once(data, "\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
replace(data, "\r", ""); replace(data, "\r", "");
lstring line; lstring line;
@ -38,16 +49,12 @@ public:
trim_once(part[1], "\""); trim_once(part[1], "\"");
unsigned n = index_input.size(); unsigned n = index_input.size();
index_input[n] = strdup(part[0]); index_input[n] = part[0];
index_output[n] = strdup(part[1]); index_output[n] = part[1];
} }
} }
void reset() { void reset() {
for(unsigned i = 0; i < index_input.size(); i++) {
free(index_input[i]);
free(index_output[i]);
}
index_input.reset(); index_input.reset();
index_output.reset(); index_output.reset();
} }
@ -56,9 +63,9 @@ public:
reset(); reset();
} }
private: protected:
array<char*> index_input; lstring index_input;
array<char*> index_output; lstring index_output;
}; };
} //namespace nall } //namespace nall

View File

@ -165,12 +165,12 @@ void AudioInterface::driver(const char *driver) {
const char* AudioInterface::default_driver() { const char* AudioInterface::default_driver() {
#if defined(AUDIO_DIRECTSOUND) #if defined(AUDIO_DIRECTSOUND)
return "DirectSound"; return "DirectSound";
#elif defined(AUDIO_AO)
return "libao";
#elif defined(AUDIO_ALSA) #elif defined(AUDIO_ALSA)
return "ALSA"; return "ALSA";
#elif defined(AUDIO_OPENAL) #elif defined(AUDIO_OPENAL)
return "OpenAL"; return "OpenAL";
#elif defined(AUDIO_AO)
return "libao";
#elif defined(AUDIO_OSS) #elif defined(AUDIO_OSS)
return "OSS"; return "OSS";
#else #else

View File

@ -80,20 +80,23 @@ double AudioInterface::hermite(double mu1, double a, double b, double c, double
} }
void AudioInterface::sample(uint16_t left, uint16_t right) { void AudioInterface::sample(uint16_t left, uint16_t right) {
int s_left = (int16_t)left;
int s_right = (int16_t)right;
if(volume != 100) { if(volume != 100) {
left = sclamp<16>((double)left * (double)volume / 100.0); s_left = sclamp<16>((double)s_left * (double)volume / 100.0);
right = sclamp<16>((double)right * (double)volume / 100.0); s_right = sclamp<16>((double)s_right * (double)volume / 100.0);
} }
r_left [0] = r_left [1]; r_left [0] = r_left [1];
r_left [1] = r_left [2]; r_left [1] = r_left [2];
r_left [2] = r_left [3]; r_left [2] = r_left [3];
r_left [3] = (int16_t)left; r_left [3] = s_left;
r_right[0] = r_right[1]; r_right[0] = r_right[1];
r_right[1] = r_right[2]; r_right[1] = r_right[2];
r_right[2] = r_right[3]; r_right[2] = r_right[3];
r_right[3] = (int16_t)right; r_right[3] = s_right;
if(resample_enabled == false) { if(resample_enabled == false) {
if(p) p->sample(left, right); if(p) p->sample(left, right);

View File

@ -221,7 +221,7 @@ void MainWindow::setup() {
menu_settings_videofilter.attach(menu_settings_videofilter_swscanline.create(group, translate["Scanline"])); menu_settings_videofilter.attach(menu_settings_videofilter_swscanline.create(group, translate["Scanline"]));
menu_settings_videofilter.attach(menu_settings_videofilter_swscale2x.create(group, translate["Scale2x"])); menu_settings_videofilter.attach(menu_settings_videofilter_swscale2x.create(group, translate["Scale2x"]));
menu_settings_videofilter.attach(menu_settings_videofilter_swhq2x.create(group, translate["HQ2x"])); menu_settings_videofilter.attach(menu_settings_videofilter_swhq2x.create(group, translate["HQ2x"]));
menu_settings_videofilter.attach(menu_settings_videofilter_swntsc.create(group, translate["NTSC"])); menu_settings_videofilter.attach(menu_settings_videofilter_swntsc.create(group, translate["{{filter}}NTSC"]));
group.reset(); group.reset();
menu_settings.attach(menu_settings_videoframeskip.create(translate["Video Frameskip"])); menu_settings.attach(menu_settings_videoframeskip.create(translate["Video Frameskip"]));
@ -264,8 +264,8 @@ void MainWindow::setup() {
menu_settings_emuspeed_fastest.create(group, translate["200%"]); menu_settings_emuspeed_fastest.create(group, translate["200%"]);
group.reset(); group.reset();
menu_settings_emuspeed_sep1.create(); menu_settings_emuspeed_sep1.create();
menu_settings_emuspeed_videosync.create(translate["Sync to Video"]); menu_settings_emuspeed_videosync.create(translate["Sync Video"]);
menu_settings_emuspeed_audiosync.create(translate["Sync to Audio"]); menu_settings_emuspeed_audiosync.create(translate["Sync Audio"]);
if(audio.cap(Audio::Frequency)) { if(audio.cap(Audio::Frequency)) {
//only audio can sync to specific frequency rates; video syncs only to monitor refresh rate //only audio can sync to specific frequency rates; video syncs only to monitor refresh rate

View File

@ -109,9 +109,9 @@ struct Audio {
static integral_setting synchronize; static integral_setting synchronize;
} audio; } audio;
integral_setting Audio::output_frequency(config(), "audio.output_frequency", "Sound card audio output frequency", integral_setting::decimal, 48000); integral_setting Audio::output_frequency(config(), "audio.output_frequency", "Sound card audio output frequency", integral_setting::decimal, 48000);
integral_setting Audio::input_frequency(config(), "audio.input_frequency", "Emulator audio input frequency", integral_setting::decimal, 31950); integral_setting Audio::input_frequency(config(), "audio.input_frequency", "Emulator audio input frequency", integral_setting::decimal, 31960);
integral_setting Audio::latency(config(), "audio.latency", "Sound card latency (in ms)", integral_setting::decimal, 100); integral_setting Audio::latency(config(), "audio.latency", "Sound card latency (in ms)", integral_setting::decimal, 100);
integral_setting Audio::volume(config(), "audio.volume", "Audio volume (0 - 100)", integral_setting::decimal, 100); integral_setting Audio::volume(config(), "audio.volume", "Audio volume (10 - 100)", integral_setting::decimal, 100);
integral_setting Audio::mute(config(), "audio.mute", "Mute audio playback", integral_setting::boolean, false); integral_setting Audio::mute(config(), "audio.mute", "Mute audio playback", integral_setting::boolean, false);
integral_setting Audio::synchronize(config(), "audio.synchronize", "Synchronize to audio sample rate", integral_setting::boolean, true); integral_setting Audio::synchronize(config(), "audio.synchronize", "Synchronize to audio sample rate", integral_setting::boolean, true);

View File

@ -118,19 +118,15 @@ void update_frameskip(int speed) {
} }
void update_emulation_speed(int speed) { void update_emulation_speed(int speed) {
config::system.emulation_speed = max(0, min(4, speed)); config::system.emulation_speed = speed = max(0, min(4, speed));
double scale; double scale[] = { 0.50, 0.75, 1.00, 1.50, 2.00 };
switch(config::system.emulation_speed) { unsigned outfreq = config::audio.output_frequency;
case 0: scale = 0.50; break; //slowest unsigned infreq = config::audio.input_frequency * scale[speed] + 0.5;
case 1: scale = 0.75; break; //slow
case 2: scale = 1.00; break; //normal
case 3: scale = 1.50; break; //fast
case 4: scale = 2.00; break; //fastest
}
audio.set(Audio::ResampleOutputFrequency, config::audio.output_frequency); audio.set(Audio::Resample, outfreq != infreq); //only resample when necessary
audio.set(Audio::ResampleInputFrequency, config::audio.input_frequency * scale + 0.5); audio.set(Audio::ResampleOutputFrequency, outfreq);
audio.set(Audio::ResampleInputFrequency, infreq);
window_main.sync(); window_main.sync();
} }
@ -178,9 +174,11 @@ void update_video_settings() {
width *= multiplier; width *= multiplier;
height *= multiplier; height *= multiplier;
if(video_settings.aspect_correction == true) { if(video_settings.aspect_correction == true) {
if(video_settings.region == 0) { //NTSC if(video_settings.region == 0) {
//NTSC
width = uint( double(width) * double(config::video.aspect_ntsc_x) / double(config::video.aspect_ntsc_y) ); width = uint( double(width) * double(config::video.aspect_ntsc_x) / double(config::video.aspect_ntsc_y) );
} else { //PAL } else {
//PAL
width = uint( double(width) * double(config::video.aspect_pal_x) / double(config::video.aspect_pal_y) ); width = uint( double(width) * double(config::video.aspect_pal_x) / double(config::video.aspect_pal_y) );
} }
} }
@ -415,7 +413,7 @@ void reset() {
if(cartridge.loaded() == true) { if(cartridge.loaded() == true) {
snes.reset(); snes.reset();
status.flush(); status.flush();
status.enqueue(translate["Reset"]); status.enqueue(translate["System was reset."]);
} }
} }
@ -423,7 +421,7 @@ void power() {
if(cartridge.loaded() == true) { if(cartridge.loaded() == true) {
snes.power(); snes.power();
status.flush(); status.flush();
status.enqueue(translate["Power cycle"]); status.enqueue(translate["System power was cycled."]);
} }
} }

View File

@ -8,7 +8,7 @@ uintptr_t AdvancedWindow::list_change(event_t) {
string default_; string default_;
config::config().list[i]->get_default(default_); config::config().list[i]->get_default(default_);
desc.set_text(string() desc.set_text(string()
<< "(" << translate["Default"] << " = " << default_ << ")\n" << "(" << translate["{{advanced}}Default"] << " = " << default_ << ")\n"
<< config::config().list[i]->description); << config::config().list[i]->description);
string value_; string value_;
config::config().list[i]->get(value_); config::config().list[i]->get(value_);
@ -90,8 +90,8 @@ void AdvancedWindow::setup() {
string() << translate["Name"] << "\t" << translate["Type"] << "\t" << translate["Value"]); string() << translate["Name"] << "\t" << translate["Type"] << "\t" << translate["Value"]);
desc.create(Editbox::Multiline | Editbox::VerticalScrollAlways | Editbox::Readonly, 475, 80, translate["<description>"]); desc.create(Editbox::Multiline | Editbox::VerticalScrollAlways | Editbox::Readonly, 475, 80, translate["<description>"]);
edit_val.create(0, 265, 25, translate["<current value>"]); edit_val.create(0, 265, 25, translate["<current value>"]);
set_val.create (0, 100, 25, translate["Set"]); set_val.create (0, 100, 25, translate["{{advanced}}Set"]);
set_def.create (0, 100, 25, translate["Default"]); set_def.create (0, 100, 25, translate["{{advanced}}Default"]);
unsigned y = 0; unsigned y = 0;
attach(list, 0, y); y += 240 + 5; attach(list, 0, y); y += 240 + 5;

View File

@ -1,5 +1,5 @@
uintptr_t AudioSettingsWindow::volume_change(event_t) { uintptr_t AudioSettingsWindow::volume_change(event_t) {
config::audio.volume = 10 + volume.get_position(); config::audio.volume = 10 + svolume.get_position();
audio.set(Audio::Volume, config::audio.volume); audio.set(Audio::Volume, config::audio.volume);
sync_ui(); sync_ui();
@ -7,19 +7,18 @@ uintptr_t AudioSettingsWindow::volume_change(event_t) {
} }
uintptr_t AudioSettingsWindow::latency_change(event_t) { uintptr_t AudioSettingsWindow::latency_change(event_t) {
config::audio.latency = 25 + latency.get_position() * 5; config::audio.latency = 25 + slatency.get_position() * 5;
audio.set(Audio::Latency, config::audio.latency); audio.set(Audio::Latency, config::audio.latency);
sync_ui(); sync_ui();
return true; return true;
} }
uintptr_t AudioSettingsWindow::outputfrequency_change(event_t) { uintptr_t AudioSettingsWindow::output_change(event_t) {
switch(outputfrequency.get_position()) { default: switch(soutput.get_position()) {
case 0: config::audio.output_frequency = 32000; break; case 0: config::audio.output_frequency = 32000; break;
case 1: config::audio.output_frequency = 44100; break; case 1: config::audio.output_frequency = 44100; break; default:
case 2: config::audio.output_frequency = 48000; break; case 2: config::audio.output_frequency = 48000; break;
case 3: config::audio.output_frequency = 96000; break;
} }
audio.set(Audio::Frequency, config::audio.output_frequency); audio.set(Audio::Frequency, config::audio.output_frequency);
@ -29,8 +28,49 @@ uintptr_t AudioSettingsWindow::outputfrequency_change(event_t) {
return true; return true;
} }
uintptr_t AudioSettingsWindow::inputfrequency_change(event_t) { uintptr_t AudioSettingsWindow::input_change(event_t) {
config::audio.input_frequency = inputfrequency.get_position() + 32000 - 200; config::audio.input_frequency = sinput.get_position() + 32000 - 200;
event::update_emulation_speed(config::system.emulation_speed);
sync_ui();
return true;
}
uintptr_t AudioSettingsWindow::volume_tick(event_t) {
char t[256];
evolume.get_text(t, sizeof t);
config::audio.volume = strdec(t);
audio.set(Audio::Volume, config::audio.volume);
sync_ui();
return true;
}
uintptr_t AudioSettingsWindow::latency_tick(event_t) {
char t[256];
elatency.get_text(t, sizeof t);
config::audio.latency = strdec(t);
audio.set(Audio::Latency, config::audio.latency);
sync_ui();
return true;
}
uintptr_t AudioSettingsWindow::output_tick(event_t) {
char t[256];
eoutput.get_text(t, sizeof t);
config::audio.output_frequency = strdec(t);
audio.set(Audio::Frequency, config::audio.output_frequency);
event::update_emulation_speed(config::system.emulation_speed);
sync_ui();
return true;
}
uintptr_t AudioSettingsWindow::input_tick(event_t) {
char t[256];
einput.get_text(t, sizeof t);
config::audio.input_frequency = strdec(t);
event::update_emulation_speed(config::system.emulation_speed); event::update_emulation_speed(config::system.emulation_speed);
sync_ui(); sync_ui();
@ -42,75 +82,121 @@ void AudioSettingsWindow::sync_ui() {
<< translate["Volume:"] << " " << translate["Volume:"] << " "
<< (int)config::audio.volume << "%" << (int)config::audio.volume << "%"
); );
volume.set_position(config::audio.volume - 10);
llatency.set_text(string() llatency.set_text(string()
<< translate["Latency:"] << " " << translate["Latency:"] << " "
<< (int)config::audio.latency << "ms" << (int)config::audio.latency << "ms"
); );
latency.set_position((config::audio.latency - 25) / 5);
loutputfrequency.set_text(string() loutput.set_text(string()
<< translate["PC output frequency:"] << " " << translate["Frequency:"] << " "
<< (int)config::audio.output_frequency << "hz" << (int)config::audio.output_frequency << "hz"
); );
unsigned position;
if(config::audio.output_frequency <= 32000) position = 0;
else if(config::audio.output_frequency <= 44100) position = 1;
else if(config::audio.output_frequency <= 48000) position = 2;
else position = 3;
outputfrequency.set_position(position);
int input_freq = config::audio.input_frequency - 32000; if(config::advanced.enable == false) {
string adjust; int input_freq = config::audio.input_frequency - 32000;
if(input_freq > 0) adjust << "+"; string adjust;
adjust << input_freq; if(input_freq > 0) adjust << "+";
if(config::advanced.enable == true) { adjust << input_freq << "hz";
adjust << " (" << (int)config::audio.input_frequency << "hz)"; linput.set_text(string()
<< translate["Frequency adjust:"] << " "
<< adjust
);
} else {
linput.set_text(string() << translate["Frequency adjust:"] << " " << (int)config::audio.input_frequency << "hz");
}
if(config::advanced.enable == false) {
svolume.set_position(config::audio.volume - 10);
slatency.set_position((config::audio.latency - 25) / 5);
unsigned position;
if(config::audio.output_frequency <= 32000) position = 0;
else if(config::audio.output_frequency <= 44100) position = 1;
else position = 2;
soutput.set_position(position);
sinput.set_position(config::audio.input_frequency - 32000 + 200);
} else {
evolume.set_text(string() << (int)config::audio.volume);
elatency.set_text(string() << (int)config::audio.latency);
eoutput.set_text(string() << (int)config::audio.output_frequency);
einput.set_text(string() << (int)config::audio.input_frequency);
} }
linputfrequency.set_text(string()
<< translate["SNES input frequency adjust:"] << " "
<< adjust
);
inputfrequency.set_position(input_freq + 200);
} }
void AudioSettingsWindow::setup() { void AudioSettingsWindow::setup() {
create(0, 475, 355); create(0, 475, 355);
lvolume.create(0, 475, 18); lvolume.create(0, 235, 18);
//if advanced UI mode is disabled, volume range is 10% - 100% svolume.create(0, 475, 30, 91);
//if enabled, volume range is 10% - 200% evolume.create(0, 130, 25);
//101%+ is hidden by default, as it can cause audio quality degradation due to clamping bvolume.create(0, 100, 25, translate["{{audio}}Set"]);
volume.create(0, 475, 30, (config::advanced.enable == false ? 91 : 191));
llatency.create(0, 475, 18); llatency.create(0, 235, 18);
latency.create(0, 475, 30, 31); slatency.create(0, 475, 30, 26);
elatency.create(0, 130, 25);
blatency.create(0, 100, 25, translate["{{audio}}Set"]);
loutputfrequency.create(0, 475, 18); loutput.create(0, 235, 18);
outputfrequency.create(0, 475, 30, 4); soutput.create(0, 475, 30, 3);
eoutput.create(0, 130, 25);
boutput.create(0, 100, 25, translate["{{audio}}Set"]);
linputfrequency.create(0, 475, 18); linput.create(0, 235, 18);
inputfrequency.create(0, 475, 30, 401); sinput.create(0, 475, 30, 401);
einput.create(0, 130, 25);
binput.create(0, 100, 25, translate["{{audio}}Set"]);
unsigned y = 0; unsigned y = 0;
attach(lvolume, 0, y); y += 18; if(config::advanced.enable == false) {
attach(volume, 0, y); y += 30; attach(lvolume, 0, y); y += 18;
if(audio.cap(Audio::Latency) == true) { attach(svolume, 0, y); y += 30;
attach(llatency, 0, y); y += 18; if(audio.cap(Audio::Latency) == true) {
attach(latency, 0, y); y += 30; attach(llatency, 0, y); y += 18;
} attach(slatency, 0, y); y += 30;
if(audio.cap(Audio::Frequency) == true) { }
attach(loutputfrequency, 0, y); y += 18; if(audio.cap(Audio::Frequency) == true) {
attach(outputfrequency, 0, y); y += 30; attach(loutput, 0, y); y += 18;
} attach(soutput, 0, y); y += 30;
attach(linputfrequency, 0, y); y += 18; }
attach(inputfrequency, 0, y); y += 30; attach(linput, 0, y); y += 18;
attach(sinput, 0, y); y += 30;
} else {
attach(lvolume, 0, y);
attach(llatency, 240, y); y += 18;
volume.on_change = bind(&AudioSettingsWindow::volume_change, this); attach(evolume, 0, y);
latency.on_change = bind(&AudioSettingsWindow::latency_change, this); attach(bvolume, 135, y);
outputfrequency.on_change = bind(&AudioSettingsWindow::outputfrequency_change, this); attach(elatency, 240, y);
inputfrequency.on_change = bind(&AudioSettingsWindow::inputfrequency_change, this); attach(blatency, 375, y); y += 25 + 5;
attach(loutput, 0, y);
attach(linput, 240, y); y += 18;
attach(eoutput, 0, y);
attach(boutput, 135, y);
attach(einput, 240, y);
attach(binput, 375, y); y += 25 + 5;
if(audio.cap(Audio::Latency) == false) {
elatency.disable();
blatency.disable();
}
if(audio.cap(Audio::Frequency) == false) {
eoutput.disable();
boutput.disable();
}
}
svolume.on_change = bind(&AudioSettingsWindow::volume_change, this);
slatency.on_change = bind(&AudioSettingsWindow::latency_change, this);
soutput.on_change = bind(&AudioSettingsWindow::output_change, this);
sinput.on_change = bind(&AudioSettingsWindow::input_change, this);
bvolume.on_tick = bind(&AudioSettingsWindow::volume_tick, this);
blatency.on_tick = bind(&AudioSettingsWindow::latency_tick, this);
boutput.on_tick = bind(&AudioSettingsWindow::output_tick, this);
binput.on_tick = bind(&AudioSettingsWindow::input_tick, this);
sync_ui(); sync_ui();
} }

View File

@ -1,21 +1,34 @@
class AudioSettingsWindow : public Window { class AudioSettingsWindow : public Window {
public: public:
Label lvolume; Label lvolume;
Slider volume; Slider svolume;
Editbox evolume;
Button bvolume;
Label llatency; Label llatency;
Slider latency; Slider slatency;
Editbox elatency;
Button blatency;
Label loutputfrequency; Label loutput;
Slider outputfrequency; Slider soutput;
Editbox eoutput;
Button boutput;
Label linputfrequency; Label linput;
Slider inputfrequency; Slider sinput;
Editbox einput;
Button binput;
uintptr_t volume_change(event_t); uintptr_t volume_change(event_t);
uintptr_t latency_change(event_t); uintptr_t latency_change(event_t);
uintptr_t outputfrequency_change(event_t); uintptr_t output_change(event_t);
uintptr_t inputfrequency_change(event_t); uintptr_t input_change(event_t);
uintptr_t volume_tick(event_t);
uintptr_t latency_tick(event_t);
uintptr_t output_tick(event_t);
uintptr_t input_tick(event_t);
void sync_ui(); void sync_ui();
void setup(); void setup();

View File

@ -30,7 +30,7 @@ void DriverSelectWindow::setup() {
lstring part; lstring part;
lvideo.create(0, 155, 18, translate["Video Driver:"]); lvideo.create(0, 155, 18, translate["Video driver:"]);
cvideo.create(0, 155, 25); cvideo.create(0, 155, 25);
split(part, ";", video.driver_list()); split(part, ";", video.driver_list());
@ -39,7 +39,7 @@ void DriverSelectWindow::setup() {
if(part[i] == config::system.video) cvideo.set_selection(i); if(part[i] == config::system.video) cvideo.set_selection(i);
} }
laudio.create(0, 155, 18, translate["Audio Driver:"]); laudio.create(0, 155, 18, translate["Audio driver:"]);
caudio.create(0, 155, 25); caudio.create(0, 155, 25);
split(part, ";", audio.driver_list()); split(part, ";", audio.driver_list());
@ -48,7 +48,7 @@ void DriverSelectWindow::setup() {
if(part[i] == config::system.audio) caudio.set_selection(i); if(part[i] == config::system.audio) caudio.set_selection(i);
} }
linput.create(0, 155, 18, translate["Input Driver:"]); linput.create(0, 155, 18, translate["Input driver:"]);
cinput.create(0, 155, 25); cinput.create(0, 155, 25);
split(part, ";", input.driver_list()); split(part, ";", input.driver_list());
@ -59,31 +59,29 @@ void DriverSelectWindow::setup() {
video_caps.create(0, 475, 18); video_caps.create(0, 475, 18);
video_sync.create(0, 155, 18, translate["Synchronize"]); video_sync.create(0, 155, 18, translate["{{video}}Synchronize"]);
video_sync.disable(); video_sync.disable();
video_filter.create(0, 155, 18, translate["Hardware Filtering"]); video_filter.create(0, 155, 18, translate["Hardware filtering"]);
video_filter.disable(); video_filter.disable();
audio_caps.create(0, 475, 18); audio_caps.create(0, 475, 18);
audio_sync.create(0, 155, 18, translate["Synchronize"]); audio_sync.create(0, 155, 18, translate["{{audio}}Synchronize"]);
audio_sync.disable(); audio_sync.disable();
audio_freq.create(0, 155, 18, translate["Frequency Control"]); audio_freq.create(0, 155, 18, translate["Frequency control"]);
audio_freq.disable(); audio_freq.disable();
audio_latency.create(0, 155, 18, translate["Latency Control"]); audio_latency.create(0, 155, 18, translate["Latency control"]);
audio_latency.disable(); audio_latency.disable();
input_caps.create(0, 475, 18); input_caps.create(0, 475, 18);
input_keyboard.create(0, 155, 18, translate["Keyboard Support"]); input_keyboard.create(0, 155, 18, translate["Keyboard support"]);
input_keyboard.disable(); input_keyboard.disable();
input_joypad.create(0, 155, 18, translate["Joypad Support"]); input_joypad.create(0, 155, 18, translate["Joypad support"]);
input_joypad.disable(); input_joypad.disable();
restart_message.create(0, 475, 36, string() restart_message.create(0, 475, 36,
<< translate["Note: bsnes must be restarted for changes to take effect."] << "\n" translate["Note: bsnes must be restarted for changes to take effect."]);
<< translate["If bsnes then crashes on startup, restart it again to adjust driver settings."]
);
bool crashed = config::system.invoke_crash_handler; bool crashed = config::system.invoke_crash_handler;

View File

@ -13,15 +13,15 @@ void InputConfigWindow::setup() {
capture_pause.create (group, 0, 155, 18, translate["Pause emulation"]); capture_pause.create (group, 0, 155, 18, translate["Pause emulation"]);
config_type.create(0, 235, 25); config_type.create(0, 235, 25);
config_type.add_item(translate["Controller Port 1"]); config_type.add_item(translate["{{input}}Controller Port 1"]);
config_type.add_item(translate["Controller Port 2"]); config_type.add_item(translate["{{input}}Controller Port 2"]);
config_type.add_item(translate["User Interface"]); config_type.add_item(translate["{{input}}User Interface"]);
config_type.set_selection(0); config_type.set_selection(0);
config_subtype.create(0, 235, 25); config_subtype.create(0, 235, 25);
refresh_subtype(); refresh_subtype();
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 254, string() << translate["Name"] << "\t" << translate["Value"]); list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 254, string() << translate["{{input}}Name"] << "\t" << translate["{{input}}Value"]);
setkey.create(0, 235, 25, translate["Assign Key"]); setkey.create(0, 235, 25, translate["Assign Key"]);
setkey.disable(); setkey.disable();
clrkey.create(0, 235, 25, translate["Unassign Key"]); clrkey.create(0, 235, 25, translate["Unassign Key"]);
@ -117,7 +117,7 @@ void InputConfigWindow::refresh_list() {
unsigned length; unsigned length;
get_input_type(length); get_input_type(length);
for(unsigned i = 0; i < length; i++) { for(unsigned i = 0; i < length; i++) {
const char *name; string name;
acquire(i, name); acquire(i, name);
list.add_item(string() << name << "\t" << input_find(get_value(i))); list.add_item(string() << name << "\t" << input_find(get_value(i)));
} }
@ -154,7 +154,7 @@ uintptr_t InputConfigWindow::set_tick(event_t) {
if(pos < 0) return true; if(pos < 0) return true;
window_input_capture.index = pos; window_input_capture.index = pos;
string message = translate["Press a key to assign to $ ..."]; string message = translate["Press a key to assign to $ ..."];
const char *name; string name;
acquire(pos, name); acquire(pos, name);
replace(message, "$", name); replace(message, "$", name);
window_input_capture.label.set_text(message); window_input_capture.label.set_text(message);
@ -211,7 +211,7 @@ InputCaptureWindow::InputCaptureWindow() {
/* Misc */ /* Misc */
string_setting& InputConfigWindow::acquire(unsigned index, const char *&name) { string_setting& InputConfigWindow::acquire(unsigned index, string &name) {
#define map(n, lname) \ #define map(n, lname) \
case n: { \ case n: { \
switch(index) { \ switch(index) { \
@ -270,12 +270,12 @@ string_setting& InputConfigWindow::acquire(unsigned index, const char *&name) {
} }
uint InputConfigWindow::get_value(uint index) { uint InputConfigWindow::get_value(uint index) {
const char *name; string name;
return input_find(acquire(index, name)); return input_find(acquire(index, name));
} }
void InputConfigWindow::set_value(uint index, uint16 value) { void InputConfigWindow::set_value(uint index, uint16 value) {
const char *name; string name;
acquire(index, name) = input_find(value); acquire(index, name) = input_find(value);
input_manager.bind(); input_manager.bind();
} }

View File

@ -41,7 +41,7 @@ public:
uintptr_t set_tick(event_t); uintptr_t set_tick(event_t);
uintptr_t clr_tick(event_t); uintptr_t clr_tick(event_t);
string_setting& acquire(unsigned index, const char *&name); string_setting& acquire(unsigned index, string &name);
uint get_value(uint index); uint get_value(uint index);
void set_value(uint index, uint16 value); void set_value(uint index, uint16 value);
} window_input_config; } window_input_config;

View File

@ -79,23 +79,23 @@ void PathSettingsWindow::setup() {
lrompath.create(0, 475, 18, translate["Default game ROM path:"]); lrompath.create(0, 475, 18, translate["Default game ROM path:"]);
rompath.create(Editbox::Readonly, 265, 25); rompath.create(Editbox::Readonly, 265, 25);
romselect.create(0, 100, 25, translate["Select"]); romselect.create(0, 100, 25, translate["{{path}}Select"]);
romdefault.create(0, 100, 25, translate["Default"]); romdefault.create(0, 100, 25, translate["{{path}}Default"]);
lpatchpath.create(0, 475, 18, translate["Default UPS patch path:"]); lpatchpath.create(0, 475, 18, translate["Default UPS patch path:"]);
patchpath.create(Editbox::Readonly, 265, 25); patchpath.create(Editbox::Readonly, 265, 25);
patchselect.create(0, 100, 25, translate["Select"]); patchselect.create(0, 100, 25, translate["{{path}}Select"]);
patchdefault.create(0, 100, 25, translate["Default"]); patchdefault.create(0, 100, 25, translate["{{path}}Default"]);
lsavepath.create(0, 475, 18, translate["Default save RAM path:"]); lsavepath.create(0, 475, 18, translate["Default save RAM path:"]);
savepath.create(Editbox::Readonly, 265, 25); savepath.create(Editbox::Readonly, 265, 25);
saveselect.create(0, 100, 25, translate["Select"]); saveselect.create(0, 100, 25, translate["{{path}}Select"]);
savedefault.create(0, 100, 25, translate["Default"]); savedefault.create(0, 100, 25, translate["{{path}}Default"]);
lcheatpath.create(0, 475, 18, translate["Default cheat file path:"]); lcheatpath.create(0, 475, 18, translate["Default cheat file path:"]);
cheatpath.create(Editbox::Readonly, 265, 25); cheatpath.create(Editbox::Readonly, 265, 25);
cheatselect.create(0, 100, 25, translate["Select"]); cheatselect.create(0, 100, 25, translate["{{path}}Select"]);
cheatdefault.create(0, 100, 25, translate["Default"]); cheatdefault.create(0, 100, 25, translate["{{path}}Default"]);
unsigned y = 0; unsigned y = 0;
attach(lrompath, 0, y); y += 18; attach(lrompath, 0, y); y += 18;

View File

@ -18,7 +18,7 @@ void Status::update() {
} else if(!cartridge.loaded()) { } else if(!cartridge.loaded()) {
output = ""; output = "";
} else if(app.pause || app.autopause) { } else if(app.pause || app.autopause) {
output = translate["Paused"]; output = translate["Paused."];
} else if(ppu.status.frames_updated) { } else if(ppu.status.frames_updated) {
ppu.status.frames_updated = false; ppu.status.frames_updated = false;

View File

@ -70,7 +70,6 @@ void ui_init() {
video.set(Video::Handle, window_main.view.handle()); video.set(Video::Handle, window_main.view.handle());
video.set(Video::Synchronize, config::video.windowed.synchronize); video.set(Video::Synchronize, config::video.windowed.synchronize);
audio.set(Audio::Resample, true);
audio.set(Audio::Handle, window_main.handle()); audio.set(Audio::Handle, window_main.handle());
audio.set(Audio::Synchronize, config::audio.synchronize); audio.set(Audio::Synchronize, config::audio.synchronize);
audio.set(Audio::Volume, config::audio.volume); audio.set(Audio::Volume, config::audio.volume);
@ -79,7 +78,7 @@ void ui_init() {
input.set(Input::Handle, window_main.handle()); input.set(Input::Handle, window_main.handle());
input.set(Input::AnalogAxisResistance, config::input.analog_axis_resistance); input.set(Input::AnalogAxisResistance, config::input.analog_axis_resistance);
//sets Audio::ResampleOutputFrequency and Audio::ResampleInputFrequency //sets Audio::Resample, Audio::ResampleOutputFrequency and Audio::ResampleInputFrequency
event::update_emulation_speed(config::system.emulation_speed); event::update_emulation_speed(config::system.emulation_speed);
video.init(); video.init();