diff --git a/Makefile b/Makefile
index 5a4406a7..771e98ff 100755
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
include nall/Makefile
snes := snes
-profile := research
+profile := accuracy
ui := qt
# compiler
@@ -61,14 +61,14 @@ endif
install:
ifeq ($(platform),x)
- install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
+ install -D -m 755 out/bsnes-$(profile) $(DESTDIR)$(prefix)/bin/bsnes-$(profile)
install -D -m 644 qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
install -D -m 644 qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
endif
uninstall:
ifeq ($(platform),x)
- rm $(DESTDIR)$(prefix)/bin/bsnes
+ rm $(DESTDIR)$(prefix)/bin/bsnes-$(profile)
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
endif
diff --git a/qt/Makefile b/qt/Makefile
index f12893f3..fb4b74e0 100755
--- a/qt/Makefile
+++ b/qt/Makefile
@@ -26,7 +26,7 @@ else ifeq ($(platform),osx)
link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
else ifeq ($(platform),win)
ruby := video.direct3d video.wgl video.directdraw video.gdi video.qtraster
- ruby += audio.directsound
+ ruby += audio.directsound audio.xaudio2
ruby += input.rawinput input.directinput
link += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
diff --git a/qt/application/application.cpp b/qt/application/application.cpp
index 8fdcdc8c..7228bc46 100755
--- a/qt/application/application.cpp
+++ b/qt/application/application.cpp
@@ -61,6 +61,8 @@ void Application::locateFile(string &filename, bool createDataDirectory) {
}
int Application::main(int &argc, char **argv) {
+ CoInitialize(0);
+
app = new App(argc, argv);
#if !defined(PLATFORM_WIN)
//Windows port uses 256x256 icon from resource file
diff --git a/qt/settings/profile.cpp b/qt/settings/profile.cpp
index 4fe2705d..23b53733 100755
--- a/qt/settings/profile.cpp
+++ b/qt/settings/profile.cpp
@@ -16,75 +16,87 @@ ProfileSettingsWindow::ProfileSettingsWindow() {
layout->addWidget(profileInfo);
layout->addSpacing(Style::WidgetSpacing);
- profileResearch = new QRadioButton("Research");
- profileResearch->setStyleSheet("font-weight: bold; font-size: 12pt;");
- layout->addWidget(profileResearch);
+ profileAccuracy = new QRadioButton("Accuracy");
+ profileAccuracy->setStyleSheet(
+ "font-weight: bold;"
+ "font-size: 12pt;"
+ "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 rgba(255, 0, 0, 48), stop: 1 rgba(255, 0, 0, 0));"
+ );
+ layout->addWidget(profileAccuracy);
- profileResearchInfo = new QLabel(
+ profileAccuracyInfo = new QLabel(
"System Requirements: A super-computer cooled by LN2.
"
"Maximum accuracy, no matter the cost.
"
- "Use this mode for development purposes only."
+ "Use this mode for development or research purposes."
);
- profileResearchInfo->setStyleSheet("margin-left: 22px;");
- layout->addWidget(profileResearchInfo);
+ profileAccuracyInfo->setStyleSheet("margin-left: 22px;");
+ layout->addWidget(profileAccuracyInfo);
layout->addSpacing(Style::WidgetSpacing);
- profileBaseline = new QRadioButton("Baseline (recommended)");
- profileBaseline->setStyleSheet("font-weight: bold; font-size: 12pt;");
- layout->addWidget(profileBaseline);
+ profileCompatibility = new QRadioButton("Compatibility");
+ profileCompatibility->setStyleSheet(
+ "font-weight: bold;"
+ "font-size: 12pt;"
+ "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 rgba(0, 0, 255, 48), stop: 1 rgba(0, 0, 255, 0));"
+ );
+ layout->addWidget(profileCompatibility);
- profileBaselineInfo = new QLabel(
+ profileCompatibilityInfo = new QLabel(
"System Requirements: Intel Core Solo or AMD Athlon 64 processor.
"
"Extreme accuracy with reasonable hardware requirements in mind.
"
- "Very rarely, slight graphical glitches may appear."
+ "Very rarely, slight graphical glitches may appear in a small number of games."
);
- profileBaselineInfo->setStyleSheet("margin-left: 22px;");
- layout->addWidget(profileBaselineInfo);
+ profileCompatibilityInfo->setStyleSheet("margin-left: 22px;");
+ layout->addWidget(profileCompatibilityInfo);
layout->addSpacing(Style::WidgetSpacing);
profilePerformance = new QRadioButton("Performance");
- profilePerformance->setStyleSheet("font-weight: bold; font-size: 12pt;");
+ profilePerformance->setStyleSheet(
+ "font-weight: bold;"
+ "font-size: 12pt;"
+ "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 rgba(0, 255, 0, 48), stop: 1 rgba(0, 255, 0, 0));"
+ );
layout->addWidget(profilePerformance);
profilePerformanceInfo = new QLabel(
"System Requirements: Intel Atom, Intel Pentium IV or AMD Athlon processor.
"
- "High accuracy with reasonable sacrifices for performance.
"
+ "High accuracy with reasonable compromises for performance.
"
"Sacrifices a small degree of compatibility to run full-speed on older hardware.
"
- "Use this mode only if baseline is too slow, or if you are running on battery power."
+ "Use this mode for slower systems, or if you are running on battery power."
);
profilePerformanceInfo->setStyleSheet("margin-left: 22px;");
layout->addWidget(profilePerformanceInfo);
- if(config().system.profile == "research") {
- profileResearch->setChecked(true);
- } else if(config().system.profile == "baseline") {
- profileBaseline->setChecked(true);
+ if(config().system.profile == "accuracy") {
+ profileAccuracy->setChecked(true);
+ } else if(config().system.profile == "compatibility") {
+ profileCompatibility->setChecked(true);
} else if(config().system.profile == "performance") {
profilePerformance->setChecked(true);
} else {
- config().system.profile = "baseline";
- profileBaseline->setChecked(true);
+ config().system.profile = "compatibility";
+ profileCompatibility->setChecked(true);
QMessageBox::information(0, "First-Run Notice",
"Note: bsnes contains multiple emulation profiles.
"
- "If bsnes runs too slowly, you can double the speed by using the "
+ "If bsnes runs too slowly, you can greatly increase the speed by using the "
"'Performance' profile; or if you want even more accuracy, you can use the "
- "'Research' profile.
"
+ "'Accuracy' profile.
"
"Feel free to experiment. You can select different profiles via:
"
"Settings -> Configuration -> Profile"
);
}
- connect(profileResearch, SIGNAL(pressed()), this, SLOT(setResearchProfile()));
- connect(profileBaseline, SIGNAL(pressed()), this, SLOT(setBaselineProfile()));
+ connect(profileAccuracy, SIGNAL(pressed()), this, SLOT(setAccuracyProfile()));
+ connect(profileCompatibility, SIGNAL(pressed()), this, SLOT(setCompatibilityProfile()));
connect(profilePerformance, SIGNAL(pressed()), this, SLOT(setPerformanceProfile()));
}
-void ProfileSettingsWindow::setResearchProfile() {
- config().system.profile = "research";
+void ProfileSettingsWindow::setAccuracyProfile() {
+ config().system.profile = "accuracy";
}
-void ProfileSettingsWindow::setBaselineProfile() {
- config().system.profile = "baseline";
+void ProfileSettingsWindow::setCompatibilityProfile() {
+ config().system.profile = "compatibility";
}
void ProfileSettingsWindow::setPerformanceProfile() {
diff --git a/qt/settings/profile.moc.hpp b/qt/settings/profile.moc.hpp
index 16f06e53..cb156749 100755
--- a/qt/settings/profile.moc.hpp
+++ b/qt/settings/profile.moc.hpp
@@ -4,18 +4,18 @@ class ProfileSettingsWindow : public QWidget {
public:
QVBoxLayout *layout;
QLabel *profileInfo;
- QRadioButton *profileResearch;
- QLabel *profileResearchInfo;
- QRadioButton *profileBaseline;
- QLabel *profileBaselineInfo;
+ QRadioButton *profileAccuracy;
+ QLabel *profileAccuracyInfo;
+ QRadioButton *profileCompatibility;
+ QLabel *profileCompatibilityInfo;
QRadioButton *profilePerformance;
QLabel *profilePerformanceInfo;
ProfileSettingsWindow();
private slots:
- void setResearchProfile();
- void setBaselineProfile();
+ void setAccuracyProfile();
+ void setCompatibilityProfile();
void setPerformanceProfile();
};
diff --git a/ruby/_test/cc.bat b/ruby/_test/cc.bat
new file mode 100755
index 00000000..00b9e552
--- /dev/null
+++ b/ruby/_test/cc.bat
@@ -0,0 +1,2 @@
+@g++ -std=gnu++0x -O3 -fomit-frame-pointer -I../.. -o test test.cpp -DAUDIO_DIRECTSOUND -DAUDIO_XAUDIO2 -DINPUT_DIRECTINPUT -lole32 -luuid -ldxguid -ldsound -ldinput8
+@pause
diff --git a/ruby/_test/test.cpp b/ruby/_test/test.cpp
new file mode 100755
index 00000000..64778930
--- /dev/null
+++ b/ruby/_test/test.cpp
@@ -0,0 +1,40 @@
+#include
+#include
+using namespace nall;
+
+#include
+using namespace ruby;
+
+#include
+
+int main() {
+ CoInitialize(0);
+
+ audio.driver("XAudio2");
+ audio.set(Audio::Handle, (uintptr_t)GetDesktopWindow());
+ audio.set(Audio::Synchronize, true);
+ audio.set(Audio::Frequency, 44100U);
+ if(audio.init() == false) {
+ printf("Failed to initialize audio driver.\n");
+ getch();
+ return 0;
+ }
+
+ input.driver("DirectInput");
+ input.set(Input::Handle, (uintptr_t)GetDesktopWindow());
+ if(input.init() == false) {
+ printf("Failed to initialize input driver.\n");
+ getch();
+ return 0;
+ }
+
+ while(true) {
+ int16_t table[Scancode::Limit];
+ input.poll(table);
+ for(unsigned i = 0; i < Scancode::Limit; i++) {
+ //if(table[i]) printf("%.4x\n", i);
+ }
+ }
+
+ return 0;
+}
diff --git a/ruby/_test/test.exe b/ruby/_test/test.exe
new file mode 100755
index 00000000..8032f45a
Binary files /dev/null and b/ruby/_test/test.exe differ
diff --git a/ruby/audio/xaudio2.cpp b/ruby/audio/xaudio2.cpp
new file mode 100755
index 00000000..d6298593
--- /dev/null
+++ b/ruby/audio/xaudio2.cpp
@@ -0,0 +1,200 @@
+/*
+ audio.xaudio2 (2010-08-14)
+ author: OV2
+*/
+
+#include "xaudio2.hpp"
+#include
+
+namespace ruby {
+
+class pAudioXAudio2: public IXAudio2VoiceCallback {
+public:
+ IXAudio2 *pXAudio2;
+ IXAudio2MasteringVoice* pMasterVoice;
+ IXAudio2SourceVoice *pSourceVoice;
+
+ // inherited from IXAudio2VoiceCallback
+ STDMETHODIMP_(void) OnBufferStart(void *pBufferContext){}
+ STDMETHODIMP_(void) OnLoopEnd(void *pBufferContext){}
+ STDMETHODIMP_(void) OnStreamEnd() {}
+ STDMETHODIMP_(void) OnVoiceError(void *pBufferContext, HRESULT Error) {}
+ STDMETHODIMP_(void) OnVoiceProcessingPassEnd() {}
+ STDMETHODIMP_(void) OnVoiceProcessingPassStart(UINT32 BytesRequired) {}
+
+ struct {
+ unsigned buffers;
+ unsigned latency;
+
+ uint32_t *buffer;
+ unsigned bufferoffset;
+
+ volatile long submitbuffers;
+ unsigned writebuffer;
+ } device;
+
+ struct {
+ bool synchronize;
+ unsigned frequency;
+ unsigned latency;
+ } settings;
+
+ bool cap(const string& name) {
+ if(name == Audio::Synchronize) return true;
+ if(name == Audio::Frequency) return true;
+ if(name == Audio::Latency) return true;
+ return false;
+ }
+
+ any get(const string& name) {
+ if(name == Audio::Synchronize) return settings.synchronize;
+ if(name == Audio::Frequency) return settings.frequency;
+ if(name == Audio::Latency) return settings.latency;
+ return false;
+ }
+
+ bool set(const string& name, const any& value) {
+ if(name == Audio::Synchronize) {
+ settings.synchronize = any_cast(value);
+ if(pXAudio2) clear();
+ return true;
+ }
+
+ if(name == Audio::Frequency) {
+ settings.frequency = any_cast(value);
+ if(pXAudio2) init();
+ return true;
+ }
+
+ if(name == Audio::Latency) {
+ settings.latency = any_cast(value);
+ if(pXAudio2) init();
+ return true;
+ }
+
+ return false;
+ }
+
+ void pushbuffer(unsigned bytes,uint32_t *pAudioData) {
+ XAUDIO2_BUFFER xa2buffer={0};
+ xa2buffer.AudioBytes=bytes;
+ xa2buffer.pAudioData=reinterpret_cast(pAudioData);
+ xa2buffer.pContext=0;
+ InterlockedIncrement(&device.submitbuffers);
+ pSourceVoice->SubmitSourceBuffer(&xa2buffer);
+ }
+
+ void sample(uint16_t left, uint16_t right) {
+ device.buffer[device.writebuffer * device.latency + device.bufferoffset++] = left + (right << 16);
+ if(device.bufferoffset < device.latency) return;
+ device.bufferoffset = 0;
+
+ if(device.submitbuffers == device.buffers - 1) {
+ if(settings.synchronize == true) {
+ //wait until there is at least one other free buffer for the next sample
+ while(device.submitbuffers == device.buffers - 1) {
+ //Sleep(0);
+ }
+ } else { //we need one free buffer for the next sample, so ignore the current contents
+ return;
+ }
+ }
+
+ pushbuffer(device.latency * 4,device.buffer + device.writebuffer * device.latency);
+
+ device.writebuffer = (device.writebuffer + 1) % device.buffers;
+ }
+
+ void clear() {
+ if(!pSourceVoice) return;
+ pSourceVoice->Stop(0);
+ pSourceVoice->FlushSourceBuffers(); //calls OnBufferEnd for all currently submitted buffers
+
+ device.writebuffer = 0;
+
+ device.bufferoffset = 0;
+ if(device.buffer) memset(device.buffer, 0, device.latency * device.buffers * 4);
+
+ pSourceVoice->Start(0);
+ }
+
+ bool init() {
+ term();
+
+ device.buffers = 8;
+ device.latency = settings.frequency * settings.latency / device.buffers / 1000.0 + 0.5;
+ device.buffer = new uint32_t[device.latency * device.buffers];
+ device.bufferoffset = 0;
+ device.submitbuffers = 0;
+
+ HRESULT hr;
+ if(FAILED(hr = XAudio2Create(&pXAudio2, 0 , XAUDIO2_DEFAULT_PROCESSOR))) {
+ return false;
+ }
+
+ if(FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasterVoice, 2,
+ settings.frequency, 0, 0 , NULL))) {
+ return false;
+ }
+
+ WAVEFORMATEX wfx;
+ wfx.wFormatTag = WAVE_FORMAT_PCM;
+ wfx.nChannels = 2;
+ wfx.nSamplesPerSec = settings.frequency;
+ wfx.nBlockAlign = 4;
+ wfx.wBitsPerSample = 16;
+ wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
+ wfx.cbSize = 0;
+
+ if(FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx,
+ XAUDIO2_VOICE_NOSRC , XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL))) {
+ return false;
+ }
+
+ clear();
+ return true;
+ }
+
+ void term() {
+ if(pSourceVoice) {
+ pSourceVoice->Stop(0);
+ pSourceVoice->DestroyVoice();
+ pSourceVoice = 0;
+ }
+ if(pMasterVoice) {
+ pMasterVoice->DestroyVoice();
+ pMasterVoice = 0;
+ }
+ if(pXAudio2) {
+ pXAudio2->Release();
+ pXAudio2 = NULL;
+ }
+ if(device.buffer) {
+ delete[] device.buffer;
+ device.buffer = 0;
+ }
+ }
+
+ STDMETHODIMP_(void) OnBufferEnd(void *pBufferContext) {
+ InterlockedDecrement(&device.submitbuffers);
+ }
+
+ pAudioXAudio2() {
+ pXAudio2 = 0;
+ pMasterVoice = 0;
+ pSourceVoice = 0;
+
+ device.buffer = 0;
+ device.bufferoffset = 0;
+ device.submitbuffers = 0;
+ device.writebuffer = 0;
+
+ settings.synchronize = false;
+ settings.frequency = 22050;
+ settings.latency = 120;
+ }
+};
+
+DeclareAudio(XAudio2)
+
+};
diff --git a/ruby/audio/xaudio2.hpp b/ruby/audio/xaudio2.hpp
new file mode 100755
index 00000000..86e19471
--- /dev/null
+++ b/ruby/audio/xaudio2.hpp
@@ -0,0 +1,336 @@
+/*
+ xaudio2.hpp (2010-08-14)
+ author: OV2
+
+ ruby-specific header to provide mingw-friendly xaudio2 interfaces
+*/
+
+#ifndef XAUDIO2_RUBY_H
+#define XAUDIO2_RUBY_H
+
+#include
+
+#define DEFINE_GUID_X(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
+#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
+#define X2DEFAULT(x) =x
+
+DEFINE_CLSID_X(XAudio2, e21a7345, eb21, 468e, be, 50, 80, 4d, b9, 7c, f7, 08);
+DEFINE_CLSID_X(XAudio2_Debug, f7a76c21, 53d4, 46bb, ac, 53, 8b, 45, 9c, ae, 46, bd);
+DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
+
+DECLARE_INTERFACE(IXAudio2Voice);
+
+#define XAUDIO2_COMMIT_NOW 0
+#define XAUDIO2_DEFAULT_CHANNELS 0
+#define XAUDIO2_DEFAULT_SAMPLERATE 0
+#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f
+#define XAUDIO2_DEBUG_ENGINE 0x0001
+#define XAUDIO2_VOICE_NOSRC 0x0004
+
+typedef struct
+{
+ WAVEFORMATEX Format;
+ union
+ {
+ WORD wValidBitsPerSample;
+ WORD wSamplesPerBlock;
+ WORD wReserved;
+ } Samples;
+ DWORD dwChannelMask;
+ GUID SubFormat;
+} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
+typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
+
+typedef enum XAUDIO2_DEVICE_ROLE
+{
+ NotDefaultDevice = 0x0,
+ DefaultConsoleDevice = 0x1,
+ DefaultMultimediaDevice = 0x2,
+ DefaultCommunicationsDevice = 0x4,
+ DefaultGameDevice = 0x8,
+ GlobalDefaultDevice = 0xf,
+ InvalidDeviceRole = ~GlobalDefaultDevice
+} XAUDIO2_DEVICE_ROLE;
+
+typedef struct XAUDIO2_DEVICE_DETAILS
+{
+ WCHAR DeviceID[256];
+ WCHAR DisplayName[256];
+ XAUDIO2_DEVICE_ROLE Role;
+ WAVEFORMATEXTENSIBLE OutputFormat;
+} XAUDIO2_DEVICE_DETAILS;
+
+typedef struct XAUDIO2_VOICE_DETAILS
+{
+ UINT32 CreationFlags;
+ UINT32 InputChannels;
+ UINT32 InputSampleRate;
+} XAUDIO2_VOICE_DETAILS;
+
+typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER
+{
+ Processor1 = 0x00000001,
+ Processor2 = 0x00000002,
+ Processor3 = 0x00000004,
+ Processor4 = 0x00000008,
+ Processor5 = 0x00000010,
+ Processor6 = 0x00000020,
+ Processor7 = 0x00000040,
+ Processor8 = 0x00000080,
+ Processor9 = 0x00000100,
+ Processor10 = 0x00000200,
+ Processor11 = 0x00000400,
+ Processor12 = 0x00000800,
+ Processor13 = 0x00001000,
+ Processor14 = 0x00002000,
+ Processor15 = 0x00004000,
+ Processor16 = 0x00008000,
+ Processor17 = 0x00010000,
+ Processor18 = 0x00020000,
+ Processor19 = 0x00040000,
+ Processor20 = 0x00080000,
+ Processor21 = 0x00100000,
+ Processor22 = 0x00200000,
+ Processor23 = 0x00400000,
+ Processor24 = 0x00800000,
+ Processor25 = 0x01000000,
+ Processor26 = 0x02000000,
+ Processor27 = 0x04000000,
+ Processor28 = 0x08000000,
+ Processor29 = 0x10000000,
+ Processor30 = 0x20000000,
+ Processor31 = 0x40000000,
+ Processor32 = 0x80000000,
+ XAUDIO2_ANY_PROCESSOR = 0xffffffff,
+ XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
+} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR;
+
+typedef struct XAUDIO2_VOICE_SENDS
+{
+ UINT32 OutputCount;
+ IXAudio2Voice** pOutputVoices;
+} XAUDIO2_VOICE_SENDS;
+
+typedef struct XAUDIO2_EFFECT_DESCRIPTOR
+{
+ IUnknown* pEffect;
+ BOOL InitialState;
+ UINT32 OutputChannels;
+} XAUDIO2_EFFECT_DESCRIPTOR;
+
+typedef struct XAUDIO2_EFFECT_CHAIN
+{
+ UINT32 EffectCount;
+ const XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors;
+} XAUDIO2_EFFECT_CHAIN;
+
+typedef enum XAUDIO2_FILTER_TYPE
+{
+ LowPassFilter,
+ BandPassFilter,
+ HighPassFilter
+} XAUDIO2_FILTER_TYPE;
+
+typedef struct XAUDIO2_FILTER_PARAMETERS
+{
+ XAUDIO2_FILTER_TYPE Type;
+ float Frequency;
+ float OneOverQ;
+
+} XAUDIO2_FILTER_PARAMETERS;
+
+typedef struct XAUDIO2_BUFFER
+{
+ UINT32 Flags;
+ UINT32 AudioBytes;
+ const BYTE* pAudioData;
+ UINT32 PlayBegin;
+ UINT32 PlayLength;
+ UINT32 LoopBegin;
+ UINT32 LoopLength;
+ UINT32 LoopCount;
+ void* pContext;
+} XAUDIO2_BUFFER;
+
+typedef struct XAUDIO2_BUFFER_WMA
+{
+ const UINT32* pDecodedPacketCumulativeBytes;
+ UINT32 PacketCount;
+} XAUDIO2_BUFFER_WMA;
+
+typedef struct XAUDIO2_VOICE_STATE
+{
+ void* pCurrentBufferContext;
+ UINT32 BuffersQueued;
+ UINT64 SamplesPlayed;
+} XAUDIO2_VOICE_STATE;
+
+typedef struct XAUDIO2_PERFORMANCE_DATA
+{
+ UINT64 AudioCyclesSinceLastQuery;
+ UINT64 TotalCyclesSinceLastQuery;
+ UINT32 MinimumCyclesPerQuantum;
+ UINT32 MaximumCyclesPerQuantum;
+ UINT32 MemoryUsageInBytes;
+ UINT32 CurrentLatencyInSamples;
+ UINT32 GlitchesSinceEngineStarted;
+ UINT32 ActiveSourceVoiceCount;
+ UINT32 TotalSourceVoiceCount;
+ UINT32 ActiveSubmixVoiceCount;
+ UINT32 TotalSubmixVoiceCount;
+ UINT32 ActiveXmaSourceVoices;
+ UINT32 ActiveXmaStreams;
+} XAUDIO2_PERFORMANCE_DATA;
+
+typedef struct XAUDIO2_DEBUG_CONFIGURATION
+{
+ UINT32 TraceMask;
+ UINT32 BreakMask;
+ BOOL LogThreadID;
+ BOOL LogFileline;
+ BOOL LogFunctionName;
+ BOOL LogTiming;
+} XAUDIO2_DEBUG_CONFIGURATION;
+
+DECLARE_INTERFACE(IXAudio2EngineCallback)
+{
+ STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE;
+ STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE;
+ STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE;
+};
+
+DECLARE_INTERFACE(IXAudio2VoiceCallback)
+{
+ STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
+ STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
+ STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
+ STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE;
+ STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE;
+ STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE;
+ STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE;
+};
+
+DECLARE_INTERFACE(IXAudio2Voice)
+{
+ #define Declare_IXAudio2Voice_Methods() \
+ STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
+ STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
+ STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
+ STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \
+ STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
+ const void* pParameters, \
+ UINT32 ParametersByteSize, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void* pParameters, \
+ UINT32 ParametersByteSize) PURE; \
+ STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
+ STDMETHOD(SetVolume) (THIS_ float Volume, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \
+ STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \
+ STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
+ UINT32 SourceChannels, UINT32 DestinationChannels, \
+ const float* pLevelMatrix, \
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
+ STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
+ UINT32 SourceChannels, UINT32 DestinationChannels, \
+ float* pLevelMatrix) PURE; \
+ STDMETHOD_(void, DestroyVoice) (THIS) PURE
+
+ Declare_IXAudio2Voice_Methods();
+};
+
+
+DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice)
+{
+ Declare_IXAudio2Voice_Methods();
+};
+
+DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice)
+{
+ Declare_IXAudio2Voice_Methods();
+};
+
+DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice)
+{
+ Declare_IXAudio2Voice_Methods();
+ STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
+ STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
+ STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
+ STDMETHOD(FlushSourceBuffers) (THIS) PURE;
+ STDMETHOD(Discontinuity) (THIS) PURE;
+ STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
+ STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE;
+ STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
+ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
+ STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE;
+};
+
+DECLARE_INTERFACE_(IXAudio2, IUnknown)
+{
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE;
+ STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG, Release) (THIS) PURE;
+ STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE;
+ STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
+ STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
+ XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
+ STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
+ STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
+ STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice,
+ const WAVEFORMATEX* pSourceFormat,
+ UINT32 Flags X2DEFAULT(0),
+ float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
+ IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
+ const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
+ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
+ STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice,
+ UINT32 InputChannels, UINT32 InputSampleRate,
+ UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
+ const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
+ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
+ STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice,
+ UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
+ UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
+ UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
+ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
+ STDMETHOD(StartEngine) (THIS) PURE;
+ STDMETHOD_(void, StopEngine) (THIS) PURE;
+ STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
+ STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE;
+ STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
+ void* pReserved X2DEFAULT(NULL)) PURE;
+};
+
+__inline HRESULT XAudio2Create(IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0),
+ XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR))
+{
+ IXAudio2* pXAudio2;
+ HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? CLSID_XAudio2_Debug : CLSID_XAudio2,
+ NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2);
+ if (SUCCEEDED(hr))
+ {
+ hr = pXAudio2->Initialize(Flags, XAudio2Processor);
+ if (SUCCEEDED(hr))
+ {
+ *ppXAudio2 = pXAudio2;
+ }
+ else
+ {
+ pXAudio2->Release();
+ }
+ }
+ return hr;
+}
+#endif
diff --git a/ruby/input/directinput.cpp b/ruby/input/directinput.cpp
index cb0da3c2..6db107b2 100755
--- a/ruby/input/directinput.cpp
+++ b/ruby/input/directinput.cpp
@@ -139,16 +139,16 @@ public:
key(Keyboard::Period ) = (bool)(state[0x34] & 0x80);
key(Keyboard::Slash ) = (bool)(state[0x35] & 0x80);
- key(Keyboard::Keypad0) = (bool)(state[0x4f] & 0x80);
- key(Keyboard::Keypad1) = (bool)(state[0x50] & 0x80);
- key(Keyboard::Keypad2) = (bool)(state[0x51] & 0x80);
- key(Keyboard::Keypad3) = (bool)(state[0x4b] & 0x80);
- key(Keyboard::Keypad4) = (bool)(state[0x4c] & 0x80);
- key(Keyboard::Keypad5) = (bool)(state[0x4d] & 0x80);
- key(Keyboard::Keypad6) = (bool)(state[0x47] & 0x80);
- key(Keyboard::Keypad7) = (bool)(state[0x48] & 0x80);
- key(Keyboard::Keypad8) = (bool)(state[0x49] & 0x80);
- key(Keyboard::Keypad9) = (bool)(state[0x52] & 0x80);
+ key(Keyboard::Keypad1) = (bool)(state[0x4f] & 0x80);
+ key(Keyboard::Keypad2) = (bool)(state[0x50] & 0x80);
+ key(Keyboard::Keypad3) = (bool)(state[0x51] & 0x80);
+ key(Keyboard::Keypad4) = (bool)(state[0x4b] & 0x80);
+ key(Keyboard::Keypad5) = (bool)(state[0x4c] & 0x80);
+ key(Keyboard::Keypad6) = (bool)(state[0x4d] & 0x80);
+ key(Keyboard::Keypad7) = (bool)(state[0x47] & 0x80);
+ key(Keyboard::Keypad8) = (bool)(state[0x48] & 0x80);
+ key(Keyboard::Keypad9) = (bool)(state[0x49] & 0x80);
+ key(Keyboard::Keypad0) = (bool)(state[0x52] & 0x80);
key(Keyboard::Point ) = (bool)(state[0x53] & 0x80);
key(Keyboard::Add ) = (bool)(state[0x4e] & 0x80);
diff --git a/ruby/ruby.cpp b/ruby/ruby.cpp
index 52395973..b52c63b1 100755
--- a/ruby/ruby.cpp
+++ b/ruby/ruby.cpp
@@ -194,6 +194,10 @@ void AudioInterface::driver(const char *driver) {
else if(!strcmp(driver, "PulseAudioSimple")) p = new AudioPulseAudioSimple();
#endif
+ #ifdef AUDIO_XAUDIO2
+ else if(!strcmp(driver, "XAudio2")) p = new AudioXAudio2();
+ #endif
+
else p = new Audio();
}
@@ -201,6 +205,8 @@ void AudioInterface::driver(const char *driver) {
const char* AudioInterface::default_driver() {
#if defined(AUDIO_DIRECTSOUND)
return "DirectSound";
+ #elif defined(AUDIO_XAUDIO2)
+ return "XAudio2";
#elif defined(AUDIO_ALSA)
return "ALSA";
#elif defined(AUDIO_OPENAL)
@@ -228,6 +234,10 @@ const char* AudioInterface::driver_list() {
"DirectSound;"
#endif
+ #if defined(AUDIO_XAUDIO2)
+ "XAudio2;"
+ #endif
+
//Linux
#if defined(AUDIO_ALSA)
@@ -298,10 +308,10 @@ void InputInterface::driver(const char *driver) {
//select the *safest* available driver, not the fastest
const char* InputInterface::default_driver() {
- #if defined(INPUT_RAWINPUT)
- return "RawInput";
- #elif defined(INPUT_DIRECTINPUT)
+ #if defined(INPUT_DIRECTINPUT)
return "DirectInput";
+ #elif defined(INPUT_RAWINPUT)
+ return "RawInput";
#elif defined(INPUT_SDL)
return "SDL";
#elif defined(INPUT_X)
diff --git a/ruby/ruby_impl.cpp b/ruby/ruby_impl.cpp
index c2bdc2d1..4b7049e2 100755
--- a/ruby/ruby_impl.cpp
+++ b/ruby/ruby_impl.cpp
@@ -133,6 +133,10 @@
#include
#endif
+#ifdef AUDIO_XAUDIO2
+ #include
+#endif
+
/* Input */
#define DeclareInput(Name) \
diff --git a/snes/Makefile b/snes/Makefile
index 06f9f91f..2a4b7fe3 100755
--- a/snes/Makefile
+++ b/snes/Makefile
@@ -10,14 +10,14 @@ snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018
snes_objects += snes-msu1 snes-serial
objects += $(snes_objects)
-ifeq ($(profile),research)
- flags += -DPROFILE_RESEARCH
+ifeq ($(profile),accuracy)
+ flags += -DPROFILE_ACCURACY
snescpu := $(snes)/cpu
snessmp := $(snes)/smp
snesdsp := $(snes)/dsp
snesppu := $(snes)/ppu
-else ifeq ($(profile),baseline)
- flags += -DPROFILE_BASELINE
+else ifeq ($(profile),compatibility)
+ flags += -DPROFILE_COMPATIBILITY
snescpu := $(snes)/cpu
snessmp := $(snes)/smp
snesdsp := $(snes)/fast/dsp
diff --git a/snes/profile-research.hpp b/snes/profile-accuracy.hpp
similarity index 54%
rename from snes/profile-research.hpp
rename to snes/profile-accuracy.hpp
index ca1b8d75..006968cb 100755
--- a/snes/profile-research.hpp
+++ b/snes/profile-accuracy.hpp
@@ -1,6 +1,5 @@
namespace Info {
- static const char Profile[] = "Research";
- static const char ProfileName[] = "Superfluous";
+ static const char Profile[] = "Accuracy";
}
#include
diff --git a/snes/profile-baseline.hpp b/snes/profile-compatibility.hpp
similarity index 55%
rename from snes/profile-baseline.hpp
rename to snes/profile-compatibility.hpp
index 1ee4d403..2f551138 100755
--- a/snes/profile-baseline.hpp
+++ b/snes/profile-compatibility.hpp
@@ -1,6 +1,5 @@
namespace Info {
- static const char Profile[] = "Baseline";
- static const char ProfileName[] = "Supersedence";
+ static const char Profile[] = "Compatibility";
}
#include
diff --git a/snes/profile-performance.hpp b/snes/profile-performance.hpp
index a0040af0..d43557d6 100755
--- a/snes/profile-performance.hpp
+++ b/snes/profile-performance.hpp
@@ -1,6 +1,5 @@
namespace Info {
static const char Profile[] = "Performance";
- static const char ProfileName[] = "Supersonic";
}
#include
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 0ff0f13c..04c1a35c 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
- static const char Version[] = "067.21";
+ static const char Version[] = "067.22";
static const unsigned SerializerVersion = 12;
}
}
@@ -76,10 +76,10 @@ namespace SNES {
#include
#include
- #if defined(PROFILE_RESEARCH)
- #include "profile-research.hpp"
- #elif defined(PROFILE_BASELINE)
- #include "profile-baseline.hpp"
+ #if defined(PROFILE_ACCURACY)
+ #include "profile-accuracy.hpp"
+ #elif defined(PROFILE_COMPATIBILITY)
+ #include "profile-compatibility.hpp"
#elif defined(PROFILE_PERFORMANCE)
#include "profile-performance.hpp"
#endif