Added AStyle 2.05.1 to the wx pre-build events and formatted the wx gui code.
Options used: --style=allman --indent=tab=4 --align-pointer=type --align-reference=name --break-blocks --pad-oper --pad-header --unpad-paren --delete-empty-lines --break-closing-brackets --keep-one-line-blocks --keep-one-line-statements --convert-tabs --remove-comment-prefix --mode=c
This commit is contained in:
parent
3f0a5adf94
commit
f2274347ae
|
@ -46,14 +46,14 @@
|
|||
<GenerateManifest>true</GenerateManifest>
|
||||
<OutDir>$(ProjectDir)$(Platform)\$(Configuration)\Binary\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Platform)\$(Configuration)\Build\$(ProjectName)\</IntDir>
|
||||
<IncludePath>..\..\..\dependencies\openal-soft\include\AL\;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||
<IncludePath>..\..\..\dependencies\openal-soft\include\AL;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Platform)\$(Configuration)\Binary\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Platform)\$(Configuration)\Build\$(ProjectName)\</IntDir>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<IncludePath>..\..\..\dependencies\openal-soft\include\AL\;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||
<IncludePath>..\..\..\dependencies\openal-soft\include\AL;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>vc_mswud_x64\</OutDir>
|
||||
|
|
3224
src/wx/cmdevents.cpp
3224
src/wx/cmdevents.cpp
File diff suppressed because it is too large
Load Diff
|
@ -4,16 +4,16 @@
|
|||
class BasicDrawingPanel : public DrawingPanel, public wxPanel
|
||||
{
|
||||
public:
|
||||
BasicDrawingPanel(wxWindow *parent, int _width, int _height);
|
||||
wxWindow *GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
BasicDrawingPanel(wxWindow* parent, int _width, int _height);
|
||||
wxWindow* GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
|
||||
protected:
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC &dc);
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC &dc);
|
||||
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#ifndef NO_OGL
|
||||
|
@ -22,25 +22,25 @@ protected:
|
|||
class GLDrawingPanel : public DrawingPanel, public wxGLCanvas
|
||||
{
|
||||
public:
|
||||
GLDrawingPanel(wxWindow *parent, int _width, int _height);
|
||||
virtual ~GLDrawingPanel();
|
||||
wxWindow *GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
GLDrawingPanel(wxWindow* parent, int _width, int _height);
|
||||
virtual ~GLDrawingPanel();
|
||||
wxWindow* GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
|
||||
protected:
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void OnSize(wxSizeEvent &);
|
||||
void DrawArea(wxWindowDC &dc);
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void OnSize(wxSizeEvent &);
|
||||
void DrawArea(wxWindowDC &dc);
|
||||
#if wxCHECK_VERSION(2,9,0) || !defined(__WXMAC__)
|
||||
wxGLContext ctx;
|
||||
wxGLContext ctx;
|
||||
#endif
|
||||
bool did_init;
|
||||
void Init();
|
||||
GLuint texid, vlist;
|
||||
int texsize;
|
||||
bool did_init;
|
||||
void Init();
|
||||
GLuint texid, vlist;
|
||||
int texsize;
|
||||
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -48,18 +48,18 @@ protected:
|
|||
class DXDrawingPanel : public DrawingPanel, public wxPanel
|
||||
{
|
||||
public:
|
||||
DXDrawingPanel(wxWindow *parent, int _width, int _height);
|
||||
wxWindow *GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
DXDrawingPanel(wxWindow* parent, int _width, int _height);
|
||||
wxWindow* GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
|
||||
protected:
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC&);
|
||||
bool did_init;
|
||||
void Init();
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC &);
|
||||
bool did_init;
|
||||
void Init();
|
||||
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -69,18 +69,18 @@ protected:
|
|||
class CairoDrawingPanel : public DrawingPanel, public wxPanel
|
||||
{
|
||||
public:
|
||||
CairoDrawingPanel(wxWindow *parent, int _width, int _height);
|
||||
~CairoDrawingPanel();
|
||||
wxWindow *GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
CairoDrawingPanel(wxWindow* parent, int _width, int _height);
|
||||
~CairoDrawingPanel();
|
||||
wxWindow* GetWindow() { return this; }
|
||||
void Delete() { Destroy(); }
|
||||
|
||||
protected:
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC&);
|
||||
cairo_surface_t *conv_surf;
|
||||
void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); }
|
||||
void DrawArea(wxWindowDC &);
|
||||
cairo_surface_t* conv_surf;
|
||||
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ private:
|
|||
LPDIRECTSOUNDNOTIFY dsbNotify;
|
||||
HANDLE dsbEvent;
|
||||
WAVEFORMATEX wfx; // Primary buffer wave format
|
||||
int soundBufferLen;
|
||||
int soundBufferLen;
|
||||
int soundBufferTotalLen;
|
||||
unsigned int soundNextPosition;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
void pause(); // pause the secondary sound buffer
|
||||
void reset(); // stop and reset the secondary sound buffer
|
||||
void resume(); // resume the secondary sound buffer
|
||||
void write(u16 * finalWave, int length); // write the emulated sound to the secondary sound buffer
|
||||
void write(u16* finalWave, int length); // write the emulated sound to the secondary sound buffer
|
||||
};
|
||||
|
||||
|
||||
|
@ -47,7 +47,6 @@ DirectSound::DirectSound()
|
|||
dsbSecondary = NULL;
|
||||
dsbNotify = NULL;
|
||||
dsbEvent = NULL;
|
||||
|
||||
soundBufferTotalLen = 14700;
|
||||
soundNextPosition = 0;
|
||||
}
|
||||
|
@ -55,23 +54,28 @@ DirectSound::DirectSound()
|
|||
|
||||
DirectSound::~DirectSound()
|
||||
{
|
||||
if(dsbNotify) {
|
||||
if (dsbNotify)
|
||||
{
|
||||
dsbNotify->Release();
|
||||
dsbNotify = NULL;
|
||||
}
|
||||
|
||||
if(dsbEvent) {
|
||||
if (dsbEvent)
|
||||
{
|
||||
CloseHandle(dsbEvent);
|
||||
dsbEvent = NULL;
|
||||
}
|
||||
|
||||
if(pDirectSound) {
|
||||
if(dsbPrimary) {
|
||||
if (pDirectSound)
|
||||
{
|
||||
if (dsbPrimary)
|
||||
{
|
||||
dsbPrimary->Release();
|
||||
dsbPrimary = NULL;
|
||||
}
|
||||
|
||||
if(dsbSecondary) {
|
||||
if (dsbSecondary)
|
||||
{
|
||||
dsbSecondary->Release();
|
||||
dsbSecondary = NULL;
|
||||
}
|
||||
|
@ -88,39 +92,47 @@ bool DirectSound::init(long sampleRate)
|
|||
DWORD freq;
|
||||
DSBUFFERDESC dsbdesc;
|
||||
int i;
|
||||
hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID*)&pDirectSound);
|
||||
|
||||
hr = CoCreateInstance( CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID *)&pDirectSound );
|
||||
if( hr != S_OK ) {
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("Cannot create DirectSound %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
GUID dev;
|
||||
if(gopts.audio_dev.empty())
|
||||
|
||||
if (gopts.audio_dev.empty())
|
||||
dev = DSDEVID_DefaultPlayback;
|
||||
else
|
||||
CLSIDFromString(const_cast<wxChar *>(gopts.audio_dev.wx_str()), &dev);
|
||||
pDirectSound->Initialize( &dev );
|
||||
if( hr != DS_OK ) {
|
||||
CLSIDFromString(const_cast<wxChar*>(gopts.audio_dev.wx_str()), &dev);
|
||||
|
||||
pDirectSound->Initialize(&dev);
|
||||
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
wxLogError(_("Cannot create DirectSound %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if( FAILED( hr = pDirectSound->SetCooperativeLevel( (HWND)wxGetApp().frame->GetHandle(), DSSCL_EXCLUSIVE ) ) ) {
|
||||
if (FAILED(hr = pDirectSound->SetCooperativeLevel((HWND)wxGetApp().frame->GetHandle(), DSSCL_EXCLUSIVE)))
|
||||
{
|
||||
wxLogError(_("Cannot SetCooperativeLevel %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Create primary sound buffer
|
||||
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
|
||||
ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
if( !gopts.dsound_hw_accel ) {
|
||||
|
||||
if (!gopts.dsound_hw_accel)
|
||||
{
|
||||
dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
|
||||
}
|
||||
|
||||
if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) {
|
||||
if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbPrimary, NULL)))
|
||||
{
|
||||
wxLogError(_("Cannot CreateSoundBuffer %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
@ -128,11 +140,10 @@ bool DirectSound::init(long sampleRate)
|
|||
freq = sampleRate;
|
||||
// calculate the number of samples per frame first
|
||||
// then multiply it with the size of a sample frame (16 bit * stereo)
|
||||
soundBufferLen = ( freq / 60 ) * 4;
|
||||
soundBufferLen = (freq / 60) * 4;
|
||||
soundBufferTotalLen = soundBufferLen * 10;
|
||||
soundNextPosition = 0;
|
||||
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
|
||||
ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = freq;
|
||||
|
@ -140,42 +151,50 @@ bool DirectSound::init(long sampleRate)
|
|||
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
|
||||
if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) {
|
||||
wxLogError( _("CreateSoundBuffer(primary) failed %08x"), hr );
|
||||
if (FAILED(hr = dsbPrimary->SetFormat(&wfx)))
|
||||
{
|
||||
wxLogError(_("CreateSoundBuffer(primary) failed %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Create secondary sound buffer
|
||||
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
|
||||
ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
|
||||
if( !gopts.dsound_hw_accel ) {
|
||||
|
||||
if (!gopts.dsound_hw_accel)
|
||||
{
|
||||
dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
|
||||
}
|
||||
|
||||
dsbdesc.dwBufferBytes = soundBufferTotalLen;
|
||||
dsbdesc.lpwfxFormat = &wfx;
|
||||
|
||||
if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) {
|
||||
wxLogError(_("CreateSoundBuffer(secondary) failed %08x"), hr );
|
||||
if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)))
|
||||
{
|
||||
wxLogError(_("CreateSoundBuffer(secondary) failed %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) {
|
||||
wxLogError(_("dsbSecondary->SetCurrentPosition failed %08x"), hr );
|
||||
if (FAILED(hr = dsbSecondary->SetCurrentPosition(0)))
|
||||
{
|
||||
wxLogError(_("dsbSecondary->SetCurrentPosition failed %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if( SUCCEEDED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) {
|
||||
dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
if (SUCCEEDED(hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify)))
|
||||
{
|
||||
dsbEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
DSBPOSITIONNOTIFY notify[10];
|
||||
for( i = 0; i < 10; i++ ) {
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
notify[i].dwOffset = i * soundBufferLen;
|
||||
notify[i].hEventNotify = dsbEvent;
|
||||
}
|
||||
|
||||
if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) {
|
||||
if (FAILED(dsbNotify->SetNotificationPositions(10, notify)))
|
||||
{
|
||||
dsbNotify->Release();
|
||||
dsbNotify = NULL;
|
||||
CloseHandle(dsbEvent);
|
||||
|
@ -183,10 +202,10 @@ bool DirectSound::init(long sampleRate)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Play primary buffer
|
||||
if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) {
|
||||
wxLogError( _("Cannot Play primary %08x"), hr );
|
||||
if (FAILED(hr = dsbPrimary->Play(0, 0, DSBPLAY_LOOPING)))
|
||||
{
|
||||
wxLogError(_("Cannot Play primary %08x"), hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -196,40 +215,36 @@ bool DirectSound::init(long sampleRate)
|
|||
|
||||
void DirectSound::pause()
|
||||
{
|
||||
if( dsbSecondary == NULL ) return;
|
||||
if (dsbSecondary == NULL) return;
|
||||
|
||||
DWORD status;
|
||||
dsbSecondary->GetStatus(&status);
|
||||
|
||||
dsbSecondary->GetStatus( &status );
|
||||
|
||||
if( status & DSBSTATUS_PLAYING ) dsbSecondary->Stop();
|
||||
if (status & DSBSTATUS_PLAYING) dsbSecondary->Stop();
|
||||
}
|
||||
|
||||
|
||||
void DirectSound::reset()
|
||||
{
|
||||
if( dsbSecondary == NULL ) return;
|
||||
if (dsbSecondary == NULL) return;
|
||||
|
||||
dsbSecondary->Stop();
|
||||
|
||||
dsbSecondary->SetCurrentPosition( 0 );
|
||||
|
||||
dsbSecondary->SetCurrentPosition(0);
|
||||
soundNextPosition = 0;
|
||||
}
|
||||
|
||||
|
||||
void DirectSound::resume()
|
||||
{
|
||||
if( dsbSecondary == NULL ) return;
|
||||
if (dsbSecondary == NULL) return;
|
||||
|
||||
dsbSecondary->Play( 0, 0, DSBPLAY_LOOPING );
|
||||
dsbSecondary->Play(0, 0, DSBPLAY_LOOPING);
|
||||
}
|
||||
|
||||
|
||||
void DirectSound::write(u16 * finalWave, int length)
|
||||
void DirectSound::write(u16* finalWave, int length)
|
||||
{
|
||||
if(!pDirectSound) return;
|
||||
|
||||
if (!pDirectSound) return;
|
||||
|
||||
HRESULT hr;
|
||||
DWORD status = 0;
|
||||
|
@ -239,88 +254,103 @@ void DirectSound::write(u16 * finalWave, int length)
|
|||
LPVOID lpvPtr2;
|
||||
DWORD dwBytes2 = 0;
|
||||
|
||||
if (!speedup && throttle && !gba_joybus_active) {
|
||||
if (!speedup && throttle && !gba_joybus_active)
|
||||
{
|
||||
hr = dsbSecondary->GetStatus(&status);
|
||||
if( status & DSBSTATUS_PLAYING ) {
|
||||
if( !soundPaused ) {
|
||||
while( true ) {
|
||||
|
||||
if (status & DSBSTATUS_PLAYING)
|
||||
{
|
||||
if (!soundPaused)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
dsbSecondary->GetCurrentPosition(&play, NULL);
|
||||
int BufferLeft = ((soundNextPosition <= play) ?
|
||||
play - soundNextPosition :
|
||||
soundBufferTotalLen - soundNextPosition + play);
|
||||
int BufferLeft = ((soundNextPosition <= play) ?
|
||||
play - soundNextPosition :
|
||||
soundBufferTotalLen - soundNextPosition + play);
|
||||
|
||||
if(BufferLeft > soundBufferLen)
|
||||
{
|
||||
if (BufferLeft > soundBufferTotalLen - (soundBufferLen * 3))
|
||||
soundBufferLow = true;
|
||||
break;
|
||||
}
|
||||
soundBufferLow = false;
|
||||
if (BufferLeft > soundBufferLen)
|
||||
{
|
||||
if (BufferLeft > soundBufferTotalLen - (soundBufferLen * 3))
|
||||
soundBufferLow = true;
|
||||
|
||||
if(dsbEvent) {
|
||||
WaitForSingleObject(dsbEvent, 50);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
soundBufferLow = false;
|
||||
|
||||
if (dsbEvent)
|
||||
{
|
||||
WaitForSingleObject(dsbEvent, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}/* else {
|
||||
// TODO: remove?
|
||||
setsoundPaused(true);
|
||||
}*/
|
||||
}
|
||||
|
||||
// TODO: remove?
|
||||
setsoundPaused(true);
|
||||
}*/
|
||||
}
|
||||
|
||||
// Obtain memory address of write block.
|
||||
// This will be in two parts if the block wraps around.
|
||||
if( DSERR_BUFFERLOST == ( hr = dsbSecondary->Lock(
|
||||
soundNextPosition,
|
||||
soundBufferLen,
|
||||
&lpvPtr1,
|
||||
&dwBytes1,
|
||||
&lpvPtr2,
|
||||
&dwBytes2,
|
||||
0 ) ) ) {
|
||||
// If DSERR_BUFFERLOST is returned, restore and retry lock.
|
||||
dsbSecondary->Restore();
|
||||
hr = dsbSecondary->Lock(
|
||||
soundNextPosition,
|
||||
soundBufferLen,
|
||||
&lpvPtr1,
|
||||
&dwBytes1,
|
||||
&lpvPtr2,
|
||||
&dwBytes2,
|
||||
0 );
|
||||
if (DSERR_BUFFERLOST == (hr = dsbSecondary->Lock(
|
||||
soundNextPosition,
|
||||
soundBufferLen,
|
||||
&lpvPtr1,
|
||||
&dwBytes1,
|
||||
&lpvPtr2,
|
||||
&dwBytes2,
|
||||
0)))
|
||||
{
|
||||
// If DSERR_BUFFERLOST is returned, restore and retry lock.
|
||||
dsbSecondary->Restore();
|
||||
hr = dsbSecondary->Lock(
|
||||
soundNextPosition,
|
||||
soundBufferLen,
|
||||
&lpvPtr1,
|
||||
&dwBytes1,
|
||||
&lpvPtr2,
|
||||
&dwBytes2,
|
||||
0);
|
||||
}
|
||||
|
||||
soundNextPosition += soundBufferLen;
|
||||
soundNextPosition = soundNextPosition % soundBufferTotalLen;
|
||||
|
||||
if( SUCCEEDED( hr ) ) {
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Write to pointers.
|
||||
CopyMemory( lpvPtr1, finalWave, dwBytes1 );
|
||||
if ( lpvPtr2 ) {
|
||||
CopyMemory( lpvPtr2, finalWave + dwBytes1, dwBytes2 );
|
||||
CopyMemory(lpvPtr1, finalWave, dwBytes1);
|
||||
|
||||
if (lpvPtr2)
|
||||
{
|
||||
CopyMemory(lpvPtr2, finalWave + dwBytes1, dwBytes2);
|
||||
}
|
||||
|
||||
// Release the data back to DirectSound.
|
||||
hr = dsbSecondary->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 );
|
||||
} else {
|
||||
wxLogError(_("dsbSecondary->Lock() failed: %08x"), hr );
|
||||
hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError(_("dsbSecondary->Lock() failed: %08x"), hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SoundDriver *newDirectSound()
|
||||
SoundDriver* newDirectSound()
|
||||
{
|
||||
return new DirectSound();
|
||||
}
|
||||
|
||||
struct devnames {
|
||||
wxArrayString *names, *ids;
|
||||
struct devnames
|
||||
{
|
||||
wxArrayString* names, *ids;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK DSEnumCB(LPGUID guid, LPCTSTR desc, LPCTSTR drvnam, LPVOID user)
|
||||
{
|
||||
devnames *dn = (devnames *)user;
|
||||
devnames* dn = (devnames*)user;
|
||||
dn->names->push_back(desc);
|
||||
WCHAR buf[32 + 4 + 2 + 1]; // hex digits + "-" + "{}" + \0
|
||||
StringFromGUID2(*guid, buf, sizeof(buf));
|
||||
|
|
|
@ -6,77 +6,77 @@
|
|||
// most 16-bit filters require space in src rounded up to u32
|
||||
// those that take delta take 1 src line of pixels, rounded up to u32 size
|
||||
// initial value appears to be all-0xff
|
||||
void Pixelate32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Pixelate(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void Pixelate32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Pixelate(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
// next 3*2 use Init_2xSaI(555|565) and do not take into account
|
||||
int Init_2xSaI(u32 BitFormat);
|
||||
// endianness or bit shift variables in init.
|
||||
// next 4*2 may be MMX-accelerated
|
||||
void _2xSaI32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void _2xSaI(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void _2xSaI32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
void _2xSaI(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
// void Scale_2xSaI(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Super2xSaI32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void Super2xSaI(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void SuperEagle32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void SuperEagle(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h);
|
||||
void AdMame2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void AdMame2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Super2xSaI32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
void Super2xSaI(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
void SuperEagle32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
void SuperEagle(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h);
|
||||
void AdMame2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void AdMame2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// next 4 convert to rgb24 in internal buffers first, and then back again
|
||||
void Bilinear32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Bilinear(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void BilinearPlus32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void BilinearPlus(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Scanlines32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Scanlines(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void ScanlinesTV32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Bilinear32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Bilinear(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void BilinearPlus32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void BilinearPlus(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Scanlines32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Scanlines(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void ScanlinesTV32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// "TV" here means each pixel is faded horizontally & vertically rather than
|
||||
// inserting black scanlines
|
||||
// this depends on RGB_LOW_BITS_MASK
|
||||
extern int RGB_LOW_BITS_MASK;
|
||||
void ScanlinesTV(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void ScanlinesTV(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// next 2 require calling hq2x_init first and whenever bpp changes
|
||||
void hq2x_init(unsigned bpp);
|
||||
void hq2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void lq2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void lq2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void hq2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void lq2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void lq2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// the simple ones could greatly benefit from correct usage of preprocessor..
|
||||
// in any case, they are worthless, since all renderers do "simple" or
|
||||
// better by default
|
||||
void Simple2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple3x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple4x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void Simple2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Simple2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Simple3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Simple3x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Simple4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void Simple4x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// note: 16-bit input for asm version only!
|
||||
void hq3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// this takes 32-bit input
|
||||
// (by converting to 16-bit first in asm version)
|
||||
void hq3x32_32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq3x16(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq3x32_32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void hq3x16(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// note: 16-bit input for asm version only!
|
||||
void hq4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
// this takes 32-bit input
|
||||
// (by converting to 16-bit first in asm version)
|
||||
void hq4x32_32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq4x16(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void hq4x32_32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void hq4x16(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
|
||||
void xbrz2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void xbrz3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void xbrz4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void xbrz5x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h);
|
||||
void xbrz2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void xbrz3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void xbrz4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
void xbrz5x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h);
|
||||
|
||||
// call ifc to ignore previous frame / when starting new
|
||||
void InterframeCleanup();
|
||||
// all 4 are MMX-accelerated if enabled
|
||||
void SmartIB(u8 *src, u32 spitch, int width, int height);
|
||||
void SmartIB32(u8 *src, u32 spitch, int width, int height);
|
||||
void MotionBlurIB(u8 *src, u32 spitch, int width, int height);
|
||||
void MotionBlurIB32(u8 *src, u32 spitch, int width, int height);
|
||||
void SmartIB(u8 *src, u32 spitch, int width, int starty, int height);
|
||||
void SmartIB32(u8 *src, u32 spitch, int width, int starty, int height);
|
||||
void MotionBlurIB(u8 *src, u32 spitch, int width, int starty, int height);
|
||||
void MotionBlurIB32(u8 *src, u32 spitch, int width, int starty, int height);
|
||||
void SmartIB(u8* src, u32 spitch, int width, int height);
|
||||
void SmartIB32(u8* src, u32 spitch, int width, int height);
|
||||
void MotionBlurIB(u8* src, u32 spitch, int width, int height);
|
||||
void MotionBlurIB32(u8* src, u32 spitch, int width, int height);
|
||||
void SmartIB(u8* src, u32 spitch, int width, int starty, int height);
|
||||
void SmartIB32(u8* src, u32 spitch, int width, int starty, int height);
|
||||
void MotionBlurIB(u8* src, u32 spitch, int width, int starty, int height);
|
||||
void MotionBlurIB32(u8* src, u32 spitch, int width, int starty, int height);
|
||||
|
||||
#endif /* FILTERS_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
4316
src/wx/guiinit.cpp
4316
src/wx/guiinit.cpp
File diff suppressed because it is too large
Load Diff
4132
src/wx/ioregs.h
4132
src/wx/ioregs.h
File diff suppressed because it is too large
Load Diff
|
@ -46,19 +46,19 @@ public:
|
|||
void pause(); // pause the secondary sound buffer
|
||||
void reset(); // stop and reset the secondary sound buffer
|
||||
void resume(); // play/resume the secondary sound buffer
|
||||
void write(u16 * finalWave, int length); // write the emulated sound to a sound buffer
|
||||
void write(u16* finalWave, int length); // write the emulated sound to a sound buffer
|
||||
|
||||
private:
|
||||
static OPENALFNTABLE ALFunction;
|
||||
bool initialized;
|
||||
bool buffersLoaded;
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALuint *buffer;
|
||||
ALCdevice* device;
|
||||
ALCcontext* context;
|
||||
ALuint* buffer;
|
||||
ALuint tempBuffer;
|
||||
ALuint source;
|
||||
int freq;
|
||||
int soundBufferLen;
|
||||
int soundBufferLen;
|
||||
|
||||
#ifdef LOGALL
|
||||
void debugState();
|
||||
|
@ -71,8 +71,8 @@ OpenAL::OpenAL()
|
|||
buffersLoaded = false;
|
||||
device = NULL;
|
||||
context = NULL;
|
||||
buffer = (ALuint*)malloc( gopts.audio_buffers * sizeof( ALuint ) );
|
||||
memset( buffer, 0, gopts.audio_buffers * sizeof( ALuint ) );
|
||||
buffer = (ALuint*)malloc(gopts.audio_buffers * sizeof(ALuint));
|
||||
memset(buffer, 0, gopts.audio_buffers * sizeof(ALuint));
|
||||
tempBuffer = 0;
|
||||
source = 0;
|
||||
}
|
||||
|
@ -80,33 +80,26 @@ OpenAL::OpenAL()
|
|||
|
||||
OpenAL::~OpenAL()
|
||||
{
|
||||
if( !initialized ) return;
|
||||
if (!initialized) return;
|
||||
|
||||
ALFunction.alSourceStop( source );
|
||||
ALFunction.alSourceStop(source);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alSourcei( source, AL_BUFFER, 0 );
|
||||
ALFunction.alSourcei(source, AL_BUFFER, 0);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alDeleteSources( 1, &source );
|
||||
ALFunction.alDeleteSources(1, &source);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alDeleteBuffers( gopts.audio_buffers, buffer );
|
||||
ALFunction.alDeleteBuffers(gopts.audio_buffers, buffer);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
free( buffer );
|
||||
|
||||
ALFunction.alcMakeContextCurrent( NULL );
|
||||
free(buffer);
|
||||
ALFunction.alcMakeContextCurrent(NULL);
|
||||
// Wine incorrectly returns ALC_INVALID_VALUE
|
||||
// and then fails the rest of these functions as well
|
||||
// so there will be a leak under Wine, but that's a bug in Wine, not
|
||||
// this code
|
||||
//ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alcDestroyContext( context );
|
||||
ALFunction.alcDestroyContext(context);
|
||||
//ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alcCloseDevice( device );
|
||||
ALFunction.alcCloseDevice(device);
|
||||
//ASSERT_SUCCESS;
|
||||
ALFunction.alGetError(); // reset error state
|
||||
}
|
||||
|
@ -114,81 +107,79 @@ OpenAL::~OpenAL()
|
|||
#ifdef LOGALL
|
||||
void OpenAL::debugState()
|
||||
{
|
||||
|
||||
ALint value = 0;
|
||||
ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &value );
|
||||
ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &value);
|
||||
ASSERT_SUCCESS;
|
||||
winlog(" soundPaused = %i\n", soundPaused);
|
||||
winlog(" Source:\n");
|
||||
winlog(" State: ");
|
||||
|
||||
winlog( " soundPaused = %i\n", soundPaused );
|
||||
winlog( " Source:\n" );
|
||||
winlog( " State: " );
|
||||
switch( value )
|
||||
switch (value)
|
||||
{
|
||||
case AL_INITIAL:
|
||||
winlog( "AL_INITIAL\n" );
|
||||
winlog("AL_INITIAL\n");
|
||||
break;
|
||||
|
||||
case AL_PLAYING:
|
||||
winlog( "AL_PLAYING\n" );
|
||||
winlog("AL_PLAYING\n");
|
||||
break;
|
||||
|
||||
case AL_PAUSED:
|
||||
winlog( "AL_PAUSED\n" );
|
||||
winlog("AL_PAUSED\n");
|
||||
break;
|
||||
|
||||
case AL_STOPPED:
|
||||
winlog( "AL_STOPPED\n" );
|
||||
winlog("AL_STOPPED\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
winlog( "!unknown!\n" );
|
||||
winlog("!unknown!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ALFunction.alGetSourcei( source, AL_BUFFERS_QUEUED, &value );
|
||||
ALFunction.alGetSourcei(source, AL_BUFFERS_QUEUED, &value);
|
||||
ASSERT_SUCCESS;
|
||||
winlog( " Buffers in queue: %i\n", value );
|
||||
|
||||
ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &value );
|
||||
winlog(" Buffers in queue: %i\n", value);
|
||||
ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &value);
|
||||
ASSERT_SUCCESS;
|
||||
winlog( " Buffers processed: %i\n", value );
|
||||
winlog(" Buffers processed: %i\n", value);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool OpenAL::init(long sampleRate)
|
||||
{
|
||||
winlog( "OpenAL::init\n" );
|
||||
assert( initialized == false );
|
||||
winlog("OpenAL::init\n");
|
||||
assert(initialized == false);
|
||||
|
||||
if( !LoadOAL() ) {
|
||||
wxLogError( _("OpenAL library could not be found on your system. Please install the runtime from http://openal.org") );
|
||||
if (!LoadOAL())
|
||||
{
|
||||
wxLogError(_("OpenAL library could not be found on your system. Please install the runtime from http://openal.org"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !gopts.audio_dev.empty() ) {
|
||||
device = ALFunction.alcOpenDevice( gopts.audio_dev.mb_str() );
|
||||
} else {
|
||||
device = ALFunction.alcOpenDevice( NULL );
|
||||
if (!gopts.audio_dev.empty())
|
||||
{
|
||||
device = ALFunction.alcOpenDevice(gopts.audio_dev.mb_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
device = ALFunction.alcOpenDevice(NULL);
|
||||
}
|
||||
assert( device != NULL );
|
||||
|
||||
context = ALFunction.alcCreateContext( device, NULL );
|
||||
assert( context != NULL );
|
||||
|
||||
ALCboolean retVal = ALFunction.alcMakeContextCurrent( context );
|
||||
assert( ALC_TRUE == retVal );
|
||||
|
||||
ALFunction.alGenBuffers( gopts.audio_buffers, buffer );
|
||||
assert(device != NULL);
|
||||
context = ALFunction.alcCreateContext(device, NULL);
|
||||
assert(context != NULL);
|
||||
ALCboolean retVal = ALFunction.alcMakeContextCurrent(context);
|
||||
assert(ALC_TRUE == retVal);
|
||||
ALFunction.alGenBuffers(gopts.audio_buffers, buffer);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
ALFunction.alGenSources( 1, &source );
|
||||
ALFunction.alGenSources(1, &source);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
freq = sampleRate;
|
||||
|
||||
// calculate the number of samples per frame first
|
||||
// then multiply it with the size of a sample frame (16 bit * stereo)
|
||||
soundBufferLen = ( freq / 60 ) * 4;
|
||||
|
||||
|
||||
soundBufferLen = (freq / 60) * 4;
|
||||
initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -196,142 +187,164 @@ bool OpenAL::init(long sampleRate)
|
|||
|
||||
void OpenAL::resume()
|
||||
{
|
||||
if( !initialized ) return;
|
||||
winlog( "OpenAL::resume\n" );
|
||||
if( !buffersLoaded ) return;
|
||||
if (!initialized) return;
|
||||
|
||||
winlog("OpenAL::resume\n");
|
||||
|
||||
if (!buffersLoaded) return;
|
||||
|
||||
debugState();
|
||||
|
||||
|
||||
ALint sourceState = 0;
|
||||
ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState );
|
||||
ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState);
|
||||
ASSERT_SUCCESS;
|
||||
if( sourceState != AL_PLAYING ) {
|
||||
ALFunction.alSourcePlay( source );
|
||||
|
||||
if (sourceState != AL_PLAYING)
|
||||
{
|
||||
ALFunction.alSourcePlay(source);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
|
||||
debugState();
|
||||
}
|
||||
|
||||
|
||||
void OpenAL::pause()
|
||||
{
|
||||
if( !initialized ) return;
|
||||
winlog( "OpenAL::pause\n" );
|
||||
if( !buffersLoaded ) return;
|
||||
if (!initialized) return;
|
||||
|
||||
winlog("OpenAL::pause\n");
|
||||
|
||||
if (!buffersLoaded) return;
|
||||
|
||||
debugState();
|
||||
|
||||
|
||||
ALint sourceState = 0;
|
||||
ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState );
|
||||
ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState);
|
||||
ASSERT_SUCCESS;
|
||||
if( sourceState == AL_PLAYING ) {
|
||||
ALFunction.alSourcePause( source );
|
||||
|
||||
if (sourceState == AL_PLAYING)
|
||||
{
|
||||
ALFunction.alSourcePause(source);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
|
||||
debugState();
|
||||
}
|
||||
|
||||
|
||||
void OpenAL::reset()
|
||||
{
|
||||
if( !initialized ) return;
|
||||
winlog( "OpenAL::reset\n" );
|
||||
if( !buffersLoaded ) return;
|
||||
debugState();
|
||||
if (!initialized) return;
|
||||
|
||||
winlog("OpenAL::reset\n");
|
||||
|
||||
if (!buffersLoaded) return;
|
||||
|
||||
debugState();
|
||||
ALint sourceState = 0;
|
||||
ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState );
|
||||
ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState);
|
||||
ASSERT_SUCCESS;
|
||||
if( sourceState != AL_STOPPED ) {
|
||||
ALFunction.alSourceStop( source );
|
||||
|
||||
if (sourceState != AL_STOPPED)
|
||||
{
|
||||
ALFunction.alSourceStop(source);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
|
||||
debugState();
|
||||
}
|
||||
|
||||
|
||||
void OpenAL::write(u16 * finalWave, int length)
|
||||
void OpenAL::write(u16* finalWave, int length)
|
||||
{
|
||||
if( !initialized ) return;
|
||||
winlog( "OpenAL::write\n" );
|
||||
if (!initialized) return;
|
||||
|
||||
winlog("OpenAL::write\n");
|
||||
debugState();
|
||||
|
||||
ALint sourceState = 0;
|
||||
ALint nBuffersProcessed = 0;
|
||||
|
||||
if( !buffersLoaded ) {
|
||||
if (!buffersLoaded)
|
||||
{
|
||||
// ==initial buffer filling==
|
||||
winlog( " initial buffer filling\n" );
|
||||
for( int i = 0 ; i < gopts.audio_buffers ; i++ ) {
|
||||
winlog(" initial buffer filling\n");
|
||||
|
||||
for (int i = 0 ; i < gopts.audio_buffers ; i++)
|
||||
{
|
||||
// Filling the buffers explicitly with silence would be cleaner,
|
||||
// but the very first sample is usually silence anyway.
|
||||
ALFunction.alBufferData( buffer[i], AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq );
|
||||
ALFunction.alBufferData(buffer[i], AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
|
||||
ALFunction.alSourceQueueBuffers( source, gopts.audio_buffers, buffer );
|
||||
ALFunction.alSourceQueueBuffers(source, gopts.audio_buffers, buffer);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
buffersLoaded = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// ==normal buffer refreshing==
|
||||
nBuffersProcessed = 0;
|
||||
ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &nBuffersProcessed );
|
||||
ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &nBuffersProcessed);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
if( nBuffersProcessed == gopts.audio_buffers ) {
|
||||
if (nBuffersProcessed == gopts.audio_buffers)
|
||||
{
|
||||
// we only want to know about it when we are emulating at full speed or faster:
|
||||
if( ( throttle >= 100 ) || ( throttle == 0 ) ) {
|
||||
if( systemVerbose & VERBOSE_SOUNDOUTPUT ) {
|
||||
if ((throttle >= 100) || (throttle == 0))
|
||||
{
|
||||
if (systemVerbose & VERBOSE_SOUNDOUTPUT)
|
||||
{
|
||||
static unsigned int i = 0;
|
||||
log( "OpenAL: Buffers were not refilled fast enough (i=%i)\n", i++ );
|
||||
log("OpenAL: Buffers were not refilled fast enough (i=%i)\n", i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!speedup && throttle && !gba_joybus_active) {
|
||||
if (!speedup && throttle && !gba_joybus_active)
|
||||
{
|
||||
// wait until at least one buffer has finished
|
||||
while( nBuffersProcessed == 0 ) {
|
||||
winlog( " waiting...\n" );
|
||||
while (nBuffersProcessed == 0)
|
||||
{
|
||||
winlog(" waiting...\n");
|
||||
// wait for about half the time one buffer needs to finish
|
||||
// unoptimized: ( sourceBufferLen * 1000 ) / ( freq * 2 * 2 ) * 1/2
|
||||
wxMilliSleep( soundBufferLen / ( freq >> 7 ) );
|
||||
ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &nBuffersProcessed );
|
||||
wxMilliSleep(soundBufferLen / (freq >> 7));
|
||||
ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &nBuffersProcessed);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
if( nBuffersProcessed == 0 ) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nBuffersProcessed == 0) return;
|
||||
}
|
||||
|
||||
assert( nBuffersProcessed > 0 );
|
||||
|
||||
assert(nBuffersProcessed > 0);
|
||||
// unqueue buffer
|
||||
tempBuffer = 0;
|
||||
ALFunction.alSourceUnqueueBuffers( source, 1, &tempBuffer );
|
||||
ALFunction.alSourceUnqueueBuffers(source, 1, &tempBuffer);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
// refill buffer
|
||||
ALFunction.alBufferData( tempBuffer, AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq );
|
||||
ALFunction.alBufferData(tempBuffer, AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq);
|
||||
ASSERT_SUCCESS;
|
||||
|
||||
// requeue buffer
|
||||
ALFunction.alSourceQueueBuffers( source, 1, &tempBuffer );
|
||||
ALFunction.alSourceQueueBuffers(source, 1, &tempBuffer);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
|
||||
// start playing the source if necessary
|
||||
ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState );
|
||||
ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState);
|
||||
ASSERT_SUCCESS;
|
||||
if( !soundPaused && ( sourceState != AL_PLAYING ) ) {
|
||||
ALFunction.alSourcePlay( source );
|
||||
|
||||
if (!soundPaused && (sourceState != AL_PLAYING))
|
||||
{
|
||||
ALFunction.alSourcePlay(source);
|
||||
ASSERT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
SoundDriver *newOpenAL()
|
||||
SoundDriver* newOpenAL()
|
||||
{
|
||||
winlog( "newOpenAL\n" );
|
||||
winlog("newOpenAL\n");
|
||||
return new OpenAL();
|
||||
}
|
||||
|
||||
|
@ -348,23 +361,24 @@ wxDynamicLibrary OpenAL::Lib;
|
|||
|
||||
bool OpenAL::LoadOAL()
|
||||
{
|
||||
if(!Lib.IsLoaded() &&
|
||||
if (!Lib.IsLoaded() &&
|
||||
#ifdef __WXMSW__
|
||||
// on win32, it's openal32.dll
|
||||
!Lib.Load(wxT("openal32")) &&
|
||||
// on win32, it's openal32.dll
|
||||
!Lib.Load(wxT("openal32")) &&
|
||||
#else
|
||||
#ifdef __WXMAC__
|
||||
// on macosx, it's just plain OpenAL
|
||||
!Lib.Load(wxT("OpenAL"), wxDL_NOW|wxDL_VERBATIM) &&
|
||||
// on macosx, it's just plain OpenAL
|
||||
!Lib.Load(wxT("OpenAL"), wxDL_NOW | wxDL_VERBATIM) &&
|
||||
#endif
|
||||
#endif
|
||||
// on linux, it's libopenal.so
|
||||
// try standard name on all platforms
|
||||
!Lib.Load(wxDynamicLibrary::CanonicalizeName(wxT("openal"))))
|
||||
// on linux, it's libopenal.so
|
||||
// try standard name on all platforms
|
||||
!Lib.Load(wxDynamicLibrary::CanonicalizeName(wxT("openal"))))
|
||||
return false;
|
||||
|
||||
#define loadfn(t, n) do { \
|
||||
if(!(ALFunction.n = (t)Lib.GetSymbol(wxT(#n)))) \
|
||||
return false; \
|
||||
if(!(ALFunction.n = (t)Lib.GetSymbol(wxT(#n)))) \
|
||||
return false; \
|
||||
} while(0)
|
||||
//loadfn(LPALENABLE, alEnable);
|
||||
//loadfn(LPALDISABLE, alDisable);
|
||||
|
@ -439,7 +453,6 @@ bool OpenAL::LoadOAL()
|
|||
//loadfn(LPALDOPPLERVELOCITY, alDopplerVelocity);
|
||||
//loadfn(LPALSPEEDOFSOUND, alSpeedOfSound);
|
||||
//loadfn(LPALDISTANCEMODEL, alDistanceModel);
|
||||
|
||||
loadfn(LPALCCREATECONTEXT, alcCreateContext);
|
||||
loadfn(LPALCMAKECONTEXTCURRENT, alcMakeContextCurrent);
|
||||
//loadfn(LPALCPROCESSCONTEXT, alcProcessContext);
|
||||
|
@ -470,18 +483,24 @@ bool GetOALDevices(wxArrayString &names, wxArrayString &ids)
|
|||
|
||||
bool OpenAL::GetDevices(wxArrayString &names, wxArrayString &ids)
|
||||
{
|
||||
if(!OpenAL::LoadOAL())
|
||||
if (!OpenAL::LoadOAL())
|
||||
return false;
|
||||
|
||||
#ifdef ALC_DEVICE_SPECIFIER
|
||||
if(ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_FALSE)
|
||||
|
||||
if (ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_FALSE)
|
||||
// this extension isn't critical to OpenAL operating
|
||||
return true;
|
||||
const char *devs = ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
while(*devs) {
|
||||
|
||||
const char* devs = ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
|
||||
while (*devs)
|
||||
{
|
||||
names.push_back(wxString(devs, wxConvLibc));
|
||||
ids.push_back(names[names.size() - 1]);
|
||||
devs += strlen(devs) + 1;
|
||||
}
|
||||
|
||||
#else
|
||||
// should work anyway, but must always use default driver
|
||||
return true;
|
||||
|
|
|
@ -15,17 +15,18 @@
|
|||
// since the ALC typedefs are broken on Mac:
|
||||
|
||||
#ifdef __WXMAC__
|
||||
typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
|
||||
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
|
||||
typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
|
||||
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
|
||||
typedef ALCcontext* (ALC_APIENTRY* LPALCCREATECONTEXT)(ALCdevice* device, const ALCint* attrlist);
|
||||
typedef ALCboolean(ALC_APIENTRY* LPALCMAKECONTEXTCURRENT)(ALCcontext* context);
|
||||
typedef void (ALC_APIENTRY* LPALCDESTROYCONTEXT)(ALCcontext* context);
|
||||
typedef ALCdevice* (ALC_APIENTRY* LPALCOPENDEVICE)(const ALCchar* devicename);
|
||||
typedef ALCboolean(ALC_APIENTRY* LPALCCLOSEDEVICE)(ALCdevice* device);
|
||||
typedef ALCboolean(ALC_APIENTRY* LPALCISEXTENSIONPRESENT)(ALCdevice* device, const ALCchar* extname);
|
||||
typedef const ALCchar* (ALC_APIENTRY* LPALCGETSTRING)(ALCdevice* device, ALCenum param);
|
||||
#endif
|
||||
|
||||
// no more use of copyrighted OpenAL code just to load the stupid library
|
||||
struct OPENALFNTABLE {
|
||||
struct OPENALFNTABLE
|
||||
{
|
||||
//LPALENABLE alEnable;
|
||||
//LPALDISABLE alDisable;
|
||||
//LPALISENABLED alIsEnabled;
|
||||
|
|
1573
src/wx/opts.cpp
1573
src/wx/opts.cpp
File diff suppressed because it is too large
Load Diff
152
src/wx/opts.h
152
src/wx/opts.h
|
@ -2,94 +2,96 @@
|
|||
#define WX_OPTS_H
|
||||
|
||||
#define NUM_KEYS 21
|
||||
extern const char * const joynames[NUM_KEYS];
|
||||
extern const char* const joynames[NUM_KEYS];
|
||||
extern wxJoyKeyBinding defkeys[NUM_KEYS * 2]; // keyboard + joystick defaults
|
||||
|
||||
extern struct opts_t {
|
||||
opts_t();
|
||||
// while I would normally put large objects in front to reduce gaps,
|
||||
// I instead organized this by opts.cpp table order
|
||||
extern struct opts_t
|
||||
{
|
||||
opts_t();
|
||||
// while I would normally put large objects in front to reduce gaps,
|
||||
// I instead organized this by opts.cpp table order
|
||||
|
||||
/// Display
|
||||
bool bilinear;
|
||||
int filter;
|
||||
wxString filter_plugin;
|
||||
int ifb;
|
||||
wxVideoMode fs_mode;
|
||||
int max_threads;
|
||||
int render_method;
|
||||
int video_scale;
|
||||
bool retain_aspect;
|
||||
/// Display
|
||||
bool bilinear;
|
||||
int filter;
|
||||
wxString filter_plugin;
|
||||
int ifb;
|
||||
wxVideoMode fs_mode;
|
||||
int max_threads;
|
||||
int render_method;
|
||||
int video_scale;
|
||||
bool retain_aspect;
|
||||
|
||||
/// GB
|
||||
wxString gb_bios;
|
||||
wxString gbc_bios;
|
||||
// u16 systemGbPalette[8*3];
|
||||
bool print_auto_page, print_screen_cap;
|
||||
wxString gb_rom_dir;
|
||||
/// GB
|
||||
wxString gb_bios;
|
||||
wxString gbc_bios;
|
||||
// u16 systemGbPalette[8*3];
|
||||
bool print_auto_page, print_screen_cap;
|
||||
wxString gb_rom_dir;
|
||||
wxString gbc_rom_dir;
|
||||
|
||||
/// GBA
|
||||
wxString gba_bios;
|
||||
int gba_link_type;
|
||||
wxString link_host;
|
||||
int link_proto;
|
||||
bool link_auto;
|
||||
wxString gba_rom_dir;
|
||||
/// GBA
|
||||
wxString gba_bios;
|
||||
int gba_link_type;
|
||||
wxString link_host;
|
||||
int link_proto;
|
||||
bool link_auto;
|
||||
wxString gba_rom_dir;
|
||||
|
||||
/// General
|
||||
bool autoload_state, autoload_cheats;
|
||||
wxString battery_dir;
|
||||
bool recent_freeze;
|
||||
wxString recording_dir;
|
||||
int rewind_interval;
|
||||
wxString scrshot_dir;
|
||||
wxString state_dir;
|
||||
/// General
|
||||
bool autoload_state, autoload_cheats;
|
||||
wxString battery_dir;
|
||||
bool recent_freeze;
|
||||
wxString recording_dir;
|
||||
int rewind_interval;
|
||||
wxString scrshot_dir;
|
||||
wxString state_dir;
|
||||
|
||||
/// Joypad
|
||||
wxJoyKeyBinding_v joykey_bindings[4][NUM_KEYS];
|
||||
int autofire_rate;
|
||||
int default_stick;
|
||||
/// Joypad
|
||||
wxJoyKeyBinding_v joykey_bindings[4][NUM_KEYS];
|
||||
int autofire_rate;
|
||||
int default_stick;
|
||||
|
||||
/// Keyboard
|
||||
wxAcceleratorEntry_v accels;
|
||||
/// Keyboard
|
||||
wxAcceleratorEntry_v accels;
|
||||
|
||||
/// Sound
|
||||
int audio_api;
|
||||
int audio_buffers;
|
||||
wxString audio_dev;
|
||||
int sound_en; // soundSetEnable()
|
||||
int gba_sound_filter;
|
||||
bool soundInterpolation;
|
||||
bool gb_declick;
|
||||
int gb_echo;
|
||||
bool gb_effects_config_enabled;
|
||||
bool dsound_hw_accel;
|
||||
int gb_stereo;
|
||||
bool gb_effects_config_surround;
|
||||
int sound_qual; // soundSetSampleRate() / gbSoundSetSampleRate()
|
||||
int sound_vol; // soundSetVolume()
|
||||
bool upmix; // xa2 only
|
||||
/// Sound
|
||||
int audio_api;
|
||||
int audio_buffers;
|
||||
wxString audio_dev;
|
||||
int sound_en; // soundSetEnable()
|
||||
int gba_sound_filter;
|
||||
bool soundInterpolation;
|
||||
bool gb_declick;
|
||||
int gb_echo;
|
||||
bool gb_effects_config_enabled;
|
||||
bool dsound_hw_accel;
|
||||
int gb_stereo;
|
||||
bool gb_effects_config_surround;
|
||||
int sound_qual; // soundSetSampleRate() / gbSoundSetSampleRate()
|
||||
int sound_vol; // soundSetVolume()
|
||||
bool upmix; // xa2 only
|
||||
|
||||
/// Recent
|
||||
wxFileHistory *recent;
|
||||
/// Recent
|
||||
wxFileHistory* recent;
|
||||
|
||||
/// wxWindows
|
||||
// wxWidgets-generated options (opaque)
|
||||
/// wxWindows
|
||||
// wxWidgets-generated options (opaque)
|
||||
} gopts;
|
||||
|
||||
extern struct opt_desc {
|
||||
const wxChar *opt;
|
||||
const char *cmd;
|
||||
const wxChar *desc;
|
||||
wxString *stropt;
|
||||
int *intopt;
|
||||
const wxChar *enumvals;
|
||||
int min, max;
|
||||
bool *boolopt;
|
||||
// current configured value
|
||||
wxString curstr;
|
||||
int curint;
|
||||
extern struct opt_desc
|
||||
{
|
||||
const wxChar* opt;
|
||||
const char* cmd;
|
||||
const wxChar* desc;
|
||||
wxString* stropt;
|
||||
int* intopt;
|
||||
const wxChar* enumvals;
|
||||
int min, max;
|
||||
bool* boolopt;
|
||||
// current configured value
|
||||
wxString curstr;
|
||||
int curint;
|
||||
#define curbool curint
|
||||
} opts[];
|
||||
extern const int num_opts;
|
||||
|
@ -105,6 +107,6 @@ void load_opts();
|
|||
// will detect changes and write config if necessary
|
||||
void update_opts();
|
||||
// returns true if option name correct; prints error if val invalid
|
||||
bool opt_set(const wxChar *name, const wxChar *val);
|
||||
bool opt_set(const wxChar* name, const wxChar* val);
|
||||
|
||||
#endif /* WX_OPTS_H */
|
||||
|
|
3492
src/wx/panel.cpp
3492
src/wx/panel.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,6 @@
|
|||
cd ..\..\src\wx
|
||||
cmake.exe -P copy-events.cmake
|
||||
..\..\..\dependencies\AStyle\bin\astyle --recursive --style=allman --indent=tab=4 --align-pointer=type --align-reference=name --break-blocks --pad-oper --pad-header --unpad-paren --delete-empty-lines --break-closing-brackets --keep-one-line-blocks --keep-one-line-statements --convert-tabs --remove-comment-prefix --mode=c *.cpp *.h
|
||||
cmake -P copy-events.cmake
|
||||
..\..\..\dependencies\wxrc xrc\*.xrc -o wxvbam.xrs
|
||||
..\..\..\dependencies\bin2c wxvbam.xrs builtin-xrc.h builtin_xrs
|
||||
..\..\..\dependencies\bin2c ../vba-over.ini builtin-over.h builtin_over
|
||||
|
|
1786
src/wx/sys.cpp
1786
src/wx/sys.cpp
File diff suppressed because it is too large
Load Diff
1290
src/wx/viewers.cpp
1290
src/wx/viewers.cpp
File diff suppressed because it is too large
Load Diff
1620
src/wx/viewsupt.cpp
1620
src/wx/viewsupt.cpp
File diff suppressed because it is too large
Load Diff
|
@ -5,16 +5,17 @@
|
|||
#include <wx/caret.h>
|
||||
|
||||
// avoid exporting too much stuff
|
||||
namespace Viewers {
|
||||
// common to all viewers:
|
||||
// - track in MainFrame::popups
|
||||
// - wxID_CLOSE button closes window
|
||||
// - AutoUpdate checkbox toggles calling Update() every screen refresh
|
||||
class Viewer : public wxDialog
|
||||
{
|
||||
public:
|
||||
namespace Viewers
|
||||
{
|
||||
// common to all viewers:
|
||||
// - track in MainFrame::popups
|
||||
// - wxID_CLOSE button closes window
|
||||
// - AutoUpdate checkbox toggles calling Update() every screen refresh
|
||||
class Viewer : public wxDialog
|
||||
{
|
||||
public:
|
||||
void CloseDlg(wxCloseEvent &ev);
|
||||
Viewer(const wxChar *name);
|
||||
Viewer(const wxChar* name);
|
||||
virtual ~Viewer() {}
|
||||
virtual void Update() = 0;
|
||||
bool auto_update;
|
||||
|
@ -26,25 +27,25 @@ namespace Viewers {
|
|||
void ActiveCtrlScr(wxScrollEvent &ev) { ActiveCtrl(ev); }
|
||||
void ActiveCtrlSpin(wxSpinEvent &ev) { ActiveCtrl(ev); }
|
||||
|
||||
protected:
|
||||
const wxChar *dname;
|
||||
protected:
|
||||
const wxChar* dname;
|
||||
void SetAutoUpdate(wxCommandEvent &ev) { auto_update = ev.IsChecked(); }
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
};
|
||||
|
||||
// on errors, abort program
|
||||
// on errors, abort program
|
||||
#define baddialog() do { \
|
||||
wxLogError(_("Unable to load dialog %s from resources"), dname); \
|
||||
wxGetApp().frame->Close(true); \
|
||||
return; \
|
||||
} while(0)
|
||||
|
||||
// widgets to use with auto validator
|
||||
// widgets to use with auto validator
|
||||
#define getvfld(sv, n, t, v) do { \
|
||||
t *_w = sv XRCCTRL(*this, n, t); \
|
||||
if(!_w) \
|
||||
baddialog(); \
|
||||
baddialog(); \
|
||||
_w->SetValidator(v); \
|
||||
} while(0)
|
||||
#define getradio(sv, n, var, val) \
|
||||
|
@ -57,40 +58,40 @@ namespace Viewers {
|
|||
#define LoadXRCViewer(t) do { \
|
||||
wxDialog *d = new Viewers::t##Viewer; \
|
||||
if(d) \
|
||||
d->Show(); \
|
||||
d->Show(); \
|
||||
} while(0)
|
||||
|
||||
// a list box with no horizontal scrollbar and a funky vertical scrollbar:
|
||||
// range = 1 - 500
|
||||
// but/pagesz = # of lines shown/# of lines shown - 1
|
||||
// 1-100 = normal
|
||||
// 101-200 = 10x semi-stationary
|
||||
// 201-300 = stationary @ center
|
||||
// 301-400 = 10x semi-stationary
|
||||
// 401-500 = normal
|
||||
// a list box with no horizontal scrollbar and a funky vertical scrollbar:
|
||||
// range = 1 - 500
|
||||
// but/pagesz = # of lines shown/# of lines shown - 1
|
||||
// 1-100 = normal
|
||||
// 101-200 = 10x semi-stationary
|
||||
// 201-300 = stationary @ center
|
||||
// 301-400 = 10x semi-stationary
|
||||
// 401-500 = normal
|
||||
|
||||
// note that since listboxes' size is impossible to control correctly (at
|
||||
// least with wxGTK), this uses a textctrl to display the items.
|
||||
// note that since listboxes' size is impossible to control correctly (at
|
||||
// least with wxGTK), this uses a textctrl to display the items.
|
||||
|
||||
class DisList : public wxPanel
|
||||
{
|
||||
public:
|
||||
class DisList : public wxPanel
|
||||
{
|
||||
public:
|
||||
DisList();
|
||||
// called after init to create subcontrols and size panel
|
||||
void Refit(int cols);
|
||||
void MoveSB();
|
||||
void MoveView(wxScrollEvent &ev);
|
||||
private:
|
||||
private:
|
||||
void RefillNeeded();
|
||||
public:
|
||||
public:
|
||||
// called by parent's refill handler or any other time strings have
|
||||
// changed
|
||||
void Refill();
|
||||
private:
|
||||
private:
|
||||
void Resize(wxSizeEvent &ev);
|
||||
void SetSel();
|
||||
|
||||
public:
|
||||
public:
|
||||
// make addr visible and then select it
|
||||
void SetSel(u32 addr);
|
||||
void UnSel() { issel = false; }
|
||||
|
@ -107,7 +108,7 @@ namespace Viewers {
|
|||
u32 topaddr;
|
||||
// max address for scrollbar
|
||||
u32 maxaddr;
|
||||
protected:
|
||||
protected:
|
||||
// assigned to textctrl to avoid mouse input
|
||||
void MouseEvent(wxMouseEvent &ev) {}
|
||||
// the subwidgets
|
||||
|
@ -122,42 +123,42 @@ namespace Viewers {
|
|||
bool issel;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS() // for xrc
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated when fewer lines available than needed
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_REFILL_NEEDED, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated when fewer lines available than needed
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_REFILL_NEEDED, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
// a hex editor with a funky scrollbar like above
|
||||
// a hex editor with a funky scrollbar like above
|
||||
|
||||
// since it's impossible to exercise this much control over a text
|
||||
// control, it uses a panel into which text is drawn.
|
||||
// Maybe some day the above will be changed to do that as well, since
|
||||
// it allows better mouse control as well.
|
||||
// since it's impossible to exercise this much control over a text
|
||||
// control, it uses a panel into which text is drawn.
|
||||
// Maybe some day the above will be changed to do that as well, since
|
||||
// it allows better mouse control as well.
|
||||
|
||||
class MemView : public wxPanel
|
||||
{
|
||||
public:
|
||||
class MemView : public wxPanel
|
||||
{
|
||||
public:
|
||||
MemView();
|
||||
// called after init to create subcontrols and size panel
|
||||
void Refit();
|
||||
void MoveSB();
|
||||
void MoveView(wxScrollEvent &ev);
|
||||
private:
|
||||
private:
|
||||
void RefillNeeded();
|
||||
public:
|
||||
public:
|
||||
// called by parent's refill handler or any other time strings have
|
||||
// changed
|
||||
void Refill();
|
||||
private:
|
||||
private:
|
||||
void Refill(wxDC &dc);
|
||||
void RepaintEv(wxPaintEvent &ev);
|
||||
void Repaint();
|
||||
void Resize(wxSizeEvent &ev);
|
||||
|
||||
public:
|
||||
public:
|
||||
// make addr visible
|
||||
void Show(u32 addr, bool force_update = false);
|
||||
|
||||
|
@ -176,8 +177,8 @@ namespace Viewers {
|
|||
// after write, these contain write addr and val
|
||||
u32 writeaddr, writeval;
|
||||
// when selection is made, this widget is updated w/ addr
|
||||
wxControl *addrlab;
|
||||
protected:
|
||||
wxControl* addrlab;
|
||||
protected:
|
||||
// easier than checking maxaddr
|
||||
int addrlen;
|
||||
|
||||
|
@ -186,7 +187,7 @@ namespace Viewers {
|
|||
// the subwidgets
|
||||
wxPanel disp;
|
||||
wxScrollBar sb;
|
||||
wxCaret *caret;
|
||||
wxCaret* caret;
|
||||
// cached text size
|
||||
int charheight, charwidth;
|
||||
// need to know if tc/sb have been Create()d yet
|
||||
|
@ -197,167 +198,168 @@ namespace Viewers {
|
|||
void ShowCaret();
|
||||
|
||||
DECLARE_DYNAMIC_CLASS() // for xrc
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated when write occurs
|
||||
// check writeaddr/writeval/fmt
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_WRITEVAL, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated when write occurs
|
||||
// check writeaddr/writeval/fmt
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_WRITEVAL, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
// Display a color in a square, with the RGB value to its right.
|
||||
// Display a color in a square, with the RGB value to its right.
|
||||
|
||||
// this is too hard to integrate into xrc (impossible to initialize
|
||||
// correctly) so no accomodations are made for this
|
||||
// this is too hard to integrate into xrc (impossible to initialize
|
||||
// correctly) so no accomodations are made for this
|
||||
|
||||
class ColorView : public wxControl
|
||||
{
|
||||
public:
|
||||
ColorView(wxWindow *parent, wxWindowID id);
|
||||
class ColorView : public wxControl
|
||||
{
|
||||
public:
|
||||
ColorView(wxWindow* parent, wxWindowID id);
|
||||
void SetRGB(int r, int g, int b);
|
||||
void GetRGB(int &_r, int &_g, int &_b) { _r = r; _g = g; _b = b; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int r, g, b;
|
||||
wxPanel *cp;
|
||||
wxStaticText *rt, *gt, *bt;
|
||||
};
|
||||
wxPanel* cp;
|
||||
wxStaticText* rt, *gt, *bt;
|
||||
};
|
||||
#define unkctrl(n, v) do { \
|
||||
if(!wxXmlResource::Get()->AttachUnknownControl(wxT(n), v, this)) \
|
||||
baddialog(); \
|
||||
if(!wxXmlResource::Get()->AttachUnknownControl(wxT(n), v, this)) \
|
||||
baddialog(); \
|
||||
} while(0)
|
||||
#define colorctrl(v, n) do { \
|
||||
v = new ColorView(this, XRCID(n)); \
|
||||
if(!v) \
|
||||
baddialog(); \
|
||||
baddialog(); \
|
||||
unkctrl(n, v); \
|
||||
} while(0)
|
||||
|
||||
// Display a small bitmap in jumbopixel style. If a pixel is selected, it
|
||||
// is highlighted with a border. For wxvbam, no event is generated.
|
||||
// Instead, a ColorView can be assigned to it, and on selection, that
|
||||
// widget will be updated to the selected color.
|
||||
// The whole class can also be derived to add more functionality to the
|
||||
// button click.
|
||||
// Display a small bitmap in jumbopixel style. If a pixel is selected, it
|
||||
// is highlighted with a border. For wxvbam, no event is generated.
|
||||
// Instead, a ColorView can be assigned to it, and on selection, that
|
||||
// widget will be updated to the selected color.
|
||||
// The whole class can also be derived to add more functionality to the
|
||||
// button click.
|
||||
|
||||
// It must be intialized in 3 phases: 2-phase xrc-style (new + Create()),
|
||||
// and then InitBMP()
|
||||
// It must be intialized in 3 phases: 2-phase xrc-style (new + Create()),
|
||||
// and then InitBMP()
|
||||
|
||||
class PixView : public wxPanel
|
||||
{
|
||||
public:
|
||||
class PixView : public wxPanel
|
||||
{
|
||||
public:
|
||||
PixView() : wxPanel(), bm(0) {}
|
||||
bool InitBMP(int w = 8, int h = 8, ColorView *cv = NULL);
|
||||
bool InitBMP(int w = 8, int h = 8, ColorView* cv = NULL);
|
||||
// stride is in pixels
|
||||
// format is rgb24 (aka wxImage format)
|
||||
// x/y is added to data and returned coords
|
||||
// if data == NULL, bitmap will be reset to default (all-black)
|
||||
virtual void SetData(const unsigned char *data, int stride, int x = 0,
|
||||
int y = 0);
|
||||
virtual void SetData(const unsigned char* data, int stride, int x = 0,
|
||||
int y = 0);
|
||||
// desel if out of displayed range
|
||||
void SetSel(int x, int y, bool dsel_cview_update = true);
|
||||
// -1, -1 = no sel
|
||||
void GetSel(int &x, int &y) {
|
||||
x = selx < 0 ? -1 : ox + selx;
|
||||
y = sely < 0 ? -1 : oy + sely;
|
||||
void GetSel(int &x, int &y)
|
||||
{
|
||||
x = selx < 0 ? -1 : ox + selx;
|
||||
y = sely < 0 ? -1 : oy + sely;
|
||||
}
|
||||
ColorView *cview;
|
||||
protected:
|
||||
ColorView* cview;
|
||||
protected:
|
||||
wxImage im;
|
||||
wxBitmap *bm;
|
||||
wxBitmap* bm;
|
||||
void Redraw(wxPaintEvent &ev);
|
||||
virtual void SelPoint(wxMouseEvent &ev);
|
||||
int ox, oy, selx, sely;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
};
|
||||
};
|
||||
#define pixview(v, n, w, h, cv) do { \
|
||||
v = XRCCTRL(*this, n, PixView); \
|
||||
if(!v) \
|
||||
baddialog(); \
|
||||
baddialog(); \
|
||||
v->InitBMP(w, h, cv); \
|
||||
} while(0)
|
||||
|
||||
// a graphics viewer panel; expected to be inside of a wxScrollWindow
|
||||
class GfxPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
// a graphics viewer panel; expected to be inside of a wxScrollWindow
|
||||
class GfxPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
GfxPanel() : wxPanel(), bm(0), selx(-1), sely(-1) {}
|
||||
int bmw, bmh;
|
||||
wxBitmap *bm;
|
||||
wxImage *im;
|
||||
PixView *pv;
|
||||
wxBitmap* bm;
|
||||
wxImage* im;
|
||||
PixView* pv;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void DrawBitmap(wxPaintEvent &ev);
|
||||
void Click(wxMouseEvent &ev);
|
||||
void MouseMove(wxMouseEvent &ev);
|
||||
void DoSel(wxMouseEvent &ev, bool force = false);
|
||||
private:
|
||||
private:
|
||||
int selx, sely;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated on mouse click
|
||||
// generates wxMouseEvent with coords adjusted to original bitmap
|
||||
// size regardless of scaling
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_COMMAND_GFX_CLICK, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
// event generated on mouse click
|
||||
// generates wxMouseEvent with coords adjusted to original bitmap
|
||||
// size regardless of scaling
|
||||
DECLARE_LOCAL_EVENT_TYPE(EVT_COMMAND_GFX_CLICK, 0)
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
#define EVT_GFX_CLICK(id, fun) \
|
||||
DECLARE_EVENT_TABLE_ENTRY(EVT_COMMAND_GFX_CLICK, id, wxID_ANY, wxMouseEventHandler(fun), NULL),
|
||||
|
||||
// like Viewer, common stuff to all gfx viewers
|
||||
// this is what actually manages the GfxPanel
|
||||
class GfxViewer : public Viewer
|
||||
{
|
||||
public:
|
||||
GfxViewer(const wxChar *dname, int maxw, int maxh);
|
||||
// like Viewer, common stuff to all gfx viewers
|
||||
// this is what actually manages the GfxPanel
|
||||
class GfxViewer : public Viewer
|
||||
{
|
||||
public:
|
||||
GfxViewer(const wxChar* dname, int maxw, int maxh);
|
||||
void ChangeBMP();
|
||||
void BMPSize(int w, int h);
|
||||
protected:
|
||||
protected:
|
||||
void StretchTog(wxCommandEvent &ev);
|
||||
void RefreshEv(wxCommandEvent &ev);
|
||||
void SaveBMP(wxCommandEvent &ev);
|
||||
wxImage image;
|
||||
GfxPanel *gv;
|
||||
private:
|
||||
GfxPanel* gv;
|
||||
private:
|
||||
static wxString bmp_save_dir;
|
||||
wxScrolledWindow *gvs;
|
||||
wxCheckBox *str;
|
||||
wxScrolledWindow* gvs;
|
||||
wxCheckBox* str;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
};
|
||||
|
||||
// if the jumbopixel view is all there is, maybe send a GFX_CLICK..
|
||||
class PixViewEvt : public PixView
|
||||
{
|
||||
// if the jumbopixel view is all there is, maybe send a GFX_CLICK..
|
||||
class PixViewEvt : public PixView
|
||||
{
|
||||
// generates a GFX_CLICK if a point is selected
|
||||
void SetData(const unsigned char *data, int stride, int x = 0,
|
||||
int y = 0);
|
||||
protected:
|
||||
void SetData(const unsigned char* data, int stride, int x = 0,
|
||||
int y = 0);
|
||||
protected:
|
||||
// always generates a GFX_CLICK
|
||||
void SelPoint(wxMouseEvent &ev);
|
||||
void click();
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
};
|
||||
};
|
||||
|
||||
// a display-only checkbox which does not look like it's disabled
|
||||
class DispCheckBox : public wxCheckBox
|
||||
{
|
||||
public:
|
||||
// a display-only checkbox which does not look like it's disabled
|
||||
class DispCheckBox : public wxCheckBox
|
||||
{
|
||||
public:
|
||||
bool AcceptsFocus() { return false; }
|
||||
void MouseEvent(wxMouseEvent &ev) {}
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
};
|
||||
};
|
||||
|
||||
// standard widgets in graphical viewers
|
||||
// standard widgets in graphical viewers
|
||||
|
||||
}
|
||||
#endif /* WX_VIEWSUPT_H */
|
||||
|
|
|
@ -45,7 +45,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckedListCtrl, wxListCtrl)
|
|||
IMPLEMENT_CLASS(wxCheckedListCtrl, wxListCtrl)
|
||||
#endif
|
||||
BEGIN_EVENT_TABLE(wxCheckedListCtrl, wxListCtrl)
|
||||
EVT_LEFT_DOWN(wxCheckedListCtrl::OnMouseEvent)
|
||||
EVT_LEFT_DOWN(wxCheckedListCtrl::OnMouseEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_CHECKED);
|
||||
|
@ -57,86 +57,75 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_UNCHECKED);
|
|||
// wxCHECKEDLISTCTRL
|
||||
// ------------------
|
||||
|
||||
bool wxCheckedListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pt,
|
||||
const wxSize& sz, long style, const wxValidator& validator, const wxString& name)
|
||||
bool wxCheckedListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint &pt,
|
||||
const wxSize &sz, long style, const wxValidator &validator, const wxString &name)
|
||||
{
|
||||
if (!wxListCtrl::Create(parent, id, pt, sz, style, validator, name))
|
||||
return FALSE;
|
||||
|
||||
#if CLC_VBAM_USAGE
|
||||
// support xrc by making init separate
|
||||
return Init();
|
||||
// support xrc by making init separate
|
||||
return Init();
|
||||
}
|
||||
|
||||
bool wxCheckedListCtrl::Init()
|
||||
{
|
||||
#if CLC_USE_SYSICONS
|
||||
// use native size images instead of 16x16
|
||||
wxCheckBox *cb = new wxCheckBox(GetParent(), wxID_ANY, wxEmptyString);
|
||||
wxSize cbsz = cb->GetBestSize();
|
||||
delete cb;
|
||||
m_imageList.Create(cbsz.GetWidth(), cbsz.GetHeight(), TRUE);
|
||||
// use native size images instead of 16x16
|
||||
wxCheckBox* cb = new wxCheckBox(GetParent(), wxID_ANY, wxEmptyString);
|
||||
wxSize cbsz = cb->GetBestSize();
|
||||
delete cb;
|
||||
m_imageList.Create(cbsz.GetWidth(), cbsz.GetHeight(), TRUE);
|
||||
#else
|
||||
m_imageList.Create(16, 16, TRUE);
|
||||
m_imageList.Create(16, 16, TRUE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SetImageList(&m_imageList, wxIMAGE_LIST_SMALL);
|
||||
|
||||
SetImageList(&m_imageList, wxIMAGE_LIST_SMALL);
|
||||
#if CLC_VBAM_USAGE && CLC_USE_SYSICONS
|
||||
// pasted from wxWiki
|
||||
// but with native size instead of 16x16
|
||||
// constructor only takes wxSize in 2.9+, apparently
|
||||
wxBitmap unchecked_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
checked_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
unchecked_disabled_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
checked_disabled_bmp(cbsz.GetWidth(), cbsz.GetHeight());
|
||||
|
||||
// Bitmaps must not be selected by a DC for addition to the image list but I don't see
|
||||
// a way of diselecting them in wxMemoryDC so let's just use a code block to end the scope
|
||||
{
|
||||
wxMemoryDC renderer_dc;
|
||||
|
||||
// Unchecked
|
||||
renderer_dc.SelectObject(unchecked_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), 0);
|
||||
|
||||
// Checked
|
||||
renderer_dc.SelectObject(checked_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), wxCONTROL_CHECKED);
|
||||
|
||||
// Unchecked and Disabled
|
||||
renderer_dc.SelectObject(unchecked_disabled_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), 0 | wxCONTROL_DISABLED);
|
||||
|
||||
// Checked and Disabled
|
||||
renderer_dc.SelectObject(checked_disabled_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), wxCONTROL_CHECKED | wxCONTROL_DISABLED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the add order must respect the wxCLC_XXX_IMGIDX defines in the headers !
|
||||
m_imageList.Add(unchecked_bmp);
|
||||
m_imageList.Add(checked_bmp);
|
||||
m_imageList.Add(unchecked_disabled_bmp);
|
||||
m_imageList.Add(checked_disabled_bmp);
|
||||
// pasted from wxWiki
|
||||
// but with native size instead of 16x16
|
||||
// constructor only takes wxSize in 2.9+, apparently
|
||||
wxBitmap unchecked_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
checked_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
unchecked_disabled_bmp(cbsz.GetWidth(), cbsz.GetHeight()),
|
||||
checked_disabled_bmp(cbsz.GetWidth(), cbsz.GetHeight());
|
||||
// Bitmaps must not be selected by a DC for addition to the image list but I don't see
|
||||
// a way of diselecting them in wxMemoryDC so let's just use a code block to end the scope
|
||||
{
|
||||
wxMemoryDC renderer_dc;
|
||||
// Unchecked
|
||||
renderer_dc.SelectObject(unchecked_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), 0);
|
||||
// Checked
|
||||
renderer_dc.SelectObject(checked_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), wxCONTROL_CHECKED);
|
||||
// Unchecked and Disabled
|
||||
renderer_dc.SelectObject(unchecked_disabled_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), 0 | wxCONTROL_DISABLED);
|
||||
// Checked and Disabled
|
||||
renderer_dc.SelectObject(checked_disabled_bmp);
|
||||
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
|
||||
renderer_dc.Clear();
|
||||
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16), wxCONTROL_CHECKED | wxCONTROL_DISABLED);
|
||||
}
|
||||
// the add order must respect the wxCLC_XXX_IMGIDX defines in the headers !
|
||||
m_imageList.Add(unchecked_bmp);
|
||||
m_imageList.Add(checked_bmp);
|
||||
m_imageList.Add(unchecked_disabled_bmp);
|
||||
m_imageList.Add(checked_disabled_bmp);
|
||||
#else
|
||||
// the add order must respect the wxCLC_XXX_IMGIDX defines in the headers !
|
||||
m_imageList.Add(wxIcon(unchecked_xpm));
|
||||
m_imageList.Add(wxIcon(checked_xpm));
|
||||
m_imageList.Add(wxIcon(unchecked_dis_xpm));
|
||||
m_imageList.Add(wxIcon(checked_dis_xpm));
|
||||
m_imageList.Add(wxIcon(unchecked_xpm));
|
||||
m_imageList.Add(wxIcon(checked_xpm));
|
||||
m_imageList.Add(wxIcon(unchecked_dis_xpm));
|
||||
m_imageList.Add(wxIcon(checked_dis_xpm));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -152,16 +141,17 @@ int wxCheckedListCtrl::GetItemImageFromAdditionalState(int addstate)
|
|||
return wxCLC_DISABLED_CHECKED_IMGIDX;
|
||||
else if (!checked && enabled)
|
||||
return wxCLC_UNCHECKED_IMGIDX;
|
||||
|
||||
wxASSERT(!checked && !enabled); // this is the last possibility
|
||||
|
||||
wxASSERT(!checked && !enabled); // this is the last possibility
|
||||
return wxCLC_DISABLED_UNCHECKED_IMGIDX;
|
||||
}
|
||||
|
||||
wxColour wxCheckedListCtrl::GetBgColourFromAdditionalState(int additionalstate)
|
||||
{
|
||||
if ((additionalstate & wxLIST_STATE_ENABLED) &&
|
||||
this->IsEnabled())
|
||||
this->IsEnabled())
|
||||
return *wxWHITE;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
return wxColour(212, 208, 200);
|
||||
#else
|
||||
|
@ -170,9 +160,10 @@ wxColour wxCheckedListCtrl::GetBgColourFromAdditionalState(int additionalstate)
|
|||
}
|
||||
|
||||
/* static */
|
||||
int wxCheckedListCtrl::GetAndRemoveAdditionalState(long *state, int statemask)
|
||||
int wxCheckedListCtrl::GetAndRemoveAdditionalState(long* state, int statemask)
|
||||
{
|
||||
int additionalstate = 0;
|
||||
|
||||
if (!state) return -1;
|
||||
|
||||
// extract the bits we are interested in
|
||||
|
@ -181,6 +172,7 @@ int wxCheckedListCtrl::GetAndRemoveAdditionalState(long *state, int statemask)
|
|||
|
||||
// and set them in a different variable if they are included in the statemask
|
||||
if (checked && (statemask & wxLIST_STATE_CHECKED)) additionalstate |= wxLIST_STATE_CHECKED;
|
||||
|
||||
if (enabled && (statemask & wxLIST_STATE_ENABLED)) additionalstate |= wxLIST_STATE_ENABLED;
|
||||
|
||||
// remove them from the original state var...
|
||||
|
@ -189,20 +181,19 @@ int wxCheckedListCtrl::GetAndRemoveAdditionalState(long *state, int statemask)
|
|||
return additionalstate;
|
||||
}
|
||||
|
||||
bool wxCheckedListCtrl::GetItem(wxListItem& info) const
|
||||
bool wxCheckedListCtrl::GetItem(wxListItem &info) const
|
||||
{
|
||||
// wx internal wxListCtrl::GetItem remove from the state mask the
|
||||
// wxLIST_STATE_CHECKED & wxLIST_STATE_ENABLED bits since they
|
||||
// are not part of wx standard flags... so we need to check those
|
||||
// flags against the original wxListItem's statemask...
|
||||
wxListItem original(info);
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
// we always want to retrieve also the image state for checking purposes...
|
||||
info.m_mask |= wxLIST_MASK_IMAGE;
|
||||
#endif
|
||||
|
||||
if (!wxListCtrl::GetItem(info))
|
||||
if (!wxListCtrl::GetItem(info))
|
||||
return FALSE;
|
||||
|
||||
// these are our additional supported states: read them from m_stateList
|
||||
|
@ -211,69 +202,73 @@ bool wxCheckedListCtrl::GetItem(wxListItem& info) const
|
|||
|
||||
// now intercept state requests about enable or check mode
|
||||
if ((original.m_mask & wxLIST_MASK_STATE) &&
|
||||
(original.m_stateMask & wxLIST_STATE_CHECKED)) {
|
||||
(original.m_stateMask & wxLIST_STATE_CHECKED))
|
||||
{
|
||||
info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED);
|
||||
info.m_stateMask |= wxLIST_STATE_CHECKED;
|
||||
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
|
||||
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
|
||||
}
|
||||
|
||||
if ((original.m_mask & wxLIST_MASK_STATE) &&
|
||||
(original.m_stateMask & wxLIST_STATE_ENABLED)) {
|
||||
(original.m_stateMask & wxLIST_STATE_ENABLED))
|
||||
{
|
||||
info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED);
|
||||
info.m_stateMask |= wxLIST_STATE_ENABLED;
|
||||
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
|
||||
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
|
||||
}
|
||||
|
||||
// check that state & image are synch
|
||||
#if CLC_VBAM_USAGE
|
||||
if(info.GetColumn())
|
||||
|
||||
if (info.GetColumn())
|
||||
return TRUE;
|
||||
|
||||
#endif
|
||||
#ifdef __WXDEBUG__
|
||||
|
||||
wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(),
|
||||
wxT("Something wrong ! See InsertItem()"));
|
||||
|
||||
wxT("Something wrong ! See InsertItem()"));
|
||||
// read info by image index
|
||||
bool imagecheck = (info.m_image == wxCLC_CHECKED_IMGIDX) ||
|
||||
(info.m_image == wxCLC_DISABLED_CHECKED_IMGIDX);
|
||||
(info.m_image == wxCLC_DISABLED_CHECKED_IMGIDX);
|
||||
bool imageenabled = (info.m_image == wxCLC_CHECKED_IMGIDX) ||
|
||||
(info.m_image == wxCLC_UNCHECKED_IMGIDX);
|
||||
(info.m_image == wxCLC_UNCHECKED_IMGIDX);
|
||||
wxASSERT_MSG((checked && imagecheck) || (!checked && !imagecheck),
|
||||
wxT("This is item has checked state but it's shown as unchecked (or viceversa)"));
|
||||
wxT("This is item has checked state but it's shown as unchecked (or viceversa)"));
|
||||
wxASSERT_MSG((enabled && imageenabled) || (!enabled && !imageenabled),
|
||||
wxT("This is item has enabled state but it's shown as disabled (or viceversa)"));
|
||||
wxT("This is item has enabled state but it's shown as disabled (or viceversa)"));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool wxCheckedListCtrl::SetItem(wxListItem& info)
|
||||
bool wxCheckedListCtrl::SetItem(wxListItem &info)
|
||||
{
|
||||
#if CLC_VBAM_USAGE
|
||||
|
||||
// only col 0 gets a checkbox
|
||||
if(info.GetColumn())
|
||||
if (info.GetColumn())
|
||||
return wxListCtrl::SetItem(info);
|
||||
|
||||
#endif
|
||||
// remove the checked & enabled states from the state flag:
|
||||
// we'll store them in our separate array
|
||||
int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask);
|
||||
|
||||
// set image index
|
||||
// set image index
|
||||
// we will ignore the info.m_image field since we need
|
||||
// to overwrite it...
|
||||
if (info.m_mask & wxLIST_MASK_STATE) {
|
||||
|
||||
if (info.m_mask & wxLIST_MASK_STATE)
|
||||
{
|
||||
// if some state is not included in the state mask, then get the state info
|
||||
// from our internal state array
|
||||
if (!(info.m_stateMask & wxLIST_STATE_ENABLED))
|
||||
additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED);
|
||||
|
||||
if (!(info.m_stateMask & wxLIST_STATE_CHECKED))
|
||||
additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED);
|
||||
|
||||
// state is valid: use it to determine the image to set...
|
||||
info.m_mask |= wxLIST_MASK_IMAGE;
|
||||
info.m_image = GetItemImageFromAdditionalState(additionalstate);
|
||||
|
||||
// since when changing the background color, also the foreground color
|
||||
// and the font of the item are changed, we try to respect the user
|
||||
// choices of such attributes
|
||||
|
@ -282,14 +277,12 @@ bool wxCheckedListCtrl::SetItem(wxListItem& info)
|
|||
// before wx 2.6.2 the wxListCtrl::SetItemFont function is missing
|
||||
info.SetFont(this->GetItemFont(info.GetId()));
|
||||
#endif
|
||||
|
||||
// change the background color to respect the enabled/disabled status...
|
||||
info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate));
|
||||
|
||||
m_stateList[info.m_itemId] = additionalstate;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// state is invalid; don't change image
|
||||
info.m_mask &= ~wxLIST_MASK_IMAGE;
|
||||
}
|
||||
|
@ -301,9 +294,10 @@ bool wxCheckedListCtrl::SetItem(wxListItem& info)
|
|||
long wxCheckedListCtrl::InsertItem(wxListItem &info)
|
||||
{
|
||||
int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask);
|
||||
if (!(info.m_mask & wxLIST_MASK_STATE) ||
|
||||
!(info.m_stateMask & wxLIST_STATE_ENABLED)) {
|
||||
|
||||
if (!(info.m_mask & wxLIST_MASK_STATE) ||
|
||||
!(info.m_stateMask & wxLIST_STATE_ENABLED))
|
||||
{
|
||||
// if not specified, the default additional state is ENABLED
|
||||
additionalstate = wxLIST_STATE_ENABLED;
|
||||
}
|
||||
|
@ -312,110 +306,111 @@ long wxCheckedListCtrl::InsertItem(wxListItem &info)
|
|||
info.m_mask |= wxLIST_MASK_IMAGE;
|
||||
info.m_image = GetItemImageFromAdditionalState(additionalstate);
|
||||
info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate));
|
||||
|
||||
int itemcount = GetItemCount();
|
||||
wxASSERT_MSG(info.m_itemId <= itemcount, wxT("Invalid index !"));
|
||||
wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(),
|
||||
wxT("Something wrong !"));
|
||||
if (info.m_itemId == itemcount) {
|
||||
wxT("Something wrong !"));
|
||||
|
||||
if (info.m_itemId == itemcount)
|
||||
{
|
||||
// we are adding a new item at the end of the list
|
||||
m_stateList.Add(additionalstate);
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// we must shift all following items
|
||||
m_stateList.Add(m_stateList[itemcount - 1]);
|
||||
for (int i=itemcount - 1; i > info.m_itemId; i--)
|
||||
m_stateList[i] = m_stateList[i-1];
|
||||
|
||||
for (int i = itemcount - 1; i > info.m_itemId; i--)
|
||||
m_stateList[i] = m_stateList[i - 1];
|
||||
|
||||
m_stateList[info.m_itemId] = additionalstate;
|
||||
}
|
||||
|
||||
|
||||
return wxListCtrl::InsertItem(info);
|
||||
}
|
||||
|
||||
bool wxCheckedListCtrl::SetItemState(long item, long state, long stateMask)
|
||||
{
|
||||
wxListItem li;
|
||||
li.SetId(item);
|
||||
li.SetMask(wxLIST_MASK_STATE);
|
||||
li.SetState(state);
|
||||
li.SetStateMask(stateMask);
|
||||
|
||||
// so we are sure to use wxCheckedListCtrl::SetItem
|
||||
// (and not wxListCtrl::SetItem)
|
||||
return SetItem(li);
|
||||
}
|
||||
|
||||
int wxCheckedListCtrl::GetItemState(long item, long stateMask) const
|
||||
{
|
||||
wxListItem li;
|
||||
li.SetId(item);
|
||||
li.SetMask(wxLIST_MASK_STATE);
|
||||
li.SetStateMask(stateMask);
|
||||
|
||||
// so we are sure to use wxCheckedListCtrl::GetItem
|
||||
// (and not wxListCtrl::GetItem)
|
||||
if (!GetItem(li))
|
||||
return -1;
|
||||
return li.GetState();
|
||||
}
|
||||
|
||||
long wxCheckedListCtrl::SetItem(long index, int col, const wxString& label, int WXUNUSED(imageId))
|
||||
{
|
||||
wxListItem li;
|
||||
li.SetId(index);
|
||||
li.SetColumn(col);
|
||||
li.SetText(label);
|
||||
li.SetMask(wxLIST_MASK_TEXT);
|
||||
|
||||
wxListItem li;
|
||||
li.SetId(item);
|
||||
li.SetMask(wxLIST_MASK_STATE);
|
||||
li.SetState(state);
|
||||
li.SetStateMask(stateMask);
|
||||
// so we are sure to use wxCheckedListCtrl::SetItem
|
||||
// (and not wxListCtrl::SetItem)
|
||||
return SetItem(li);
|
||||
}
|
||||
|
||||
long wxCheckedListCtrl::InsertItem( long index, const wxString& label, int WXUNUSED(imageIndex) )
|
||||
int wxCheckedListCtrl::GetItemState(long item, long stateMask) const
|
||||
{
|
||||
wxListItem info;
|
||||
info.m_text = label;
|
||||
info.m_mask = wxLIST_MASK_TEXT;
|
||||
info.m_itemId = index;
|
||||
return InsertItem(info);
|
||||
wxListItem li;
|
||||
li.SetId(item);
|
||||
li.SetMask(wxLIST_MASK_STATE);
|
||||
li.SetStateMask(stateMask);
|
||||
|
||||
// so we are sure to use wxCheckedListCtrl::GetItem
|
||||
// (and not wxListCtrl::GetItem)
|
||||
if (!GetItem(li))
|
||||
return -1;
|
||||
|
||||
return li.GetState();
|
||||
}
|
||||
|
||||
long wxCheckedListCtrl::SetItem(long index, int col, const wxString &label, int WXUNUSED(imageId))
|
||||
{
|
||||
wxListItem li;
|
||||
li.SetId(index);
|
||||
li.SetColumn(col);
|
||||
li.SetText(label);
|
||||
li.SetMask(wxLIST_MASK_TEXT);
|
||||
// so we are sure to use wxCheckedListCtrl::SetItem
|
||||
// (and not wxListCtrl::SetItem)
|
||||
return SetItem(li);
|
||||
}
|
||||
|
||||
long wxCheckedListCtrl::InsertItem(long index, const wxString &label, int WXUNUSED(imageIndex))
|
||||
{
|
||||
wxListItem info;
|
||||
info.m_text = label;
|
||||
info.m_mask = wxLIST_MASK_TEXT;
|
||||
info.m_itemId = index;
|
||||
return InsertItem(info);
|
||||
}
|
||||
|
||||
void wxCheckedListCtrl::Check(long item, bool checked)
|
||||
{
|
||||
{
|
||||
// NB: the "statemask" is not the "mask" of a list item;
|
||||
// in the "mask" you use the wxLIST_MASK_XXXX defines;
|
||||
// in the "statemask" you use the wxLIST_STATE_XXX defines
|
||||
// to set a specific bit of the wxListInfo::m_state var
|
||||
if (checked)
|
||||
if (checked)
|
||||
// the 2nd parameter says: activate the STATE bit relative to CHECK feature
|
||||
// the 3rd parameter says: set only *that* bit
|
||||
SetItemState(item, wxLIST_STATE_CHECKED, wxLIST_STATE_CHECKED);
|
||||
// the 3rd parameter says: set only *that* bit
|
||||
SetItemState(item, wxLIST_STATE_CHECKED, wxLIST_STATE_CHECKED);
|
||||
else
|
||||
SetItemState(item, 0, wxLIST_STATE_CHECKED);
|
||||
SetItemState(item, 0, wxLIST_STATE_CHECKED);
|
||||
}
|
||||
|
||||
void wxCheckedListCtrl::Enable(long item, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if (enable)
|
||||
// the 2nd parameter says: activate the STATE bit relative to ENABLE feature
|
||||
// the 3rd parameter says: set only *that* bit
|
||||
// the 3rd parameter says: set only *that* bit
|
||||
SetItemState(item, wxLIST_STATE_ENABLED, wxLIST_STATE_ENABLED);
|
||||
else
|
||||
SetItemState(item, 0, wxLIST_STATE_ENABLED);
|
||||
SetItemState(item, 0, wxLIST_STATE_ENABLED);
|
||||
}
|
||||
|
||||
void wxCheckedListCtrl::EnableAll(bool enable)
|
||||
{
|
||||
for (int i=0; i < GetItemCount(); i++)
|
||||
for (int i = 0; i < GetItemCount(); i++)
|
||||
Enable(i, enable);
|
||||
}
|
||||
|
||||
void wxCheckedListCtrl::CheckAll(bool check)
|
||||
{
|
||||
for (int i=0; i < GetItemCount(); i++)
|
||||
for (int i = 0; i < GetItemCount(); i++)
|
||||
Check(i, check);
|
||||
}
|
||||
|
||||
|
@ -423,16 +418,16 @@ bool wxCheckedListCtrl::DeleteItem(long item)
|
|||
{
|
||||
// shift our additional state array
|
||||
//for (int i=item,max=GetItemCount(); i < max-1; i++)
|
||||
// m_stateList[i] = m_stateList[i+1];
|
||||
// m_stateList[i] = m_stateList[i+1];
|
||||
m_stateList.RemoveAt(item, 1);
|
||||
|
||||
return wxListCtrl::DeleteItem(item);
|
||||
}
|
||||
|
||||
int wxCheckedListCtrl::GetCheckedItemCount() const
|
||||
{
|
||||
int res = 0;
|
||||
for (int i=0; i<GetItemCount(); i++)
|
||||
|
||||
for (int i = 0; i < GetItemCount(); i++)
|
||||
if (IsChecked(i))
|
||||
res++;
|
||||
|
||||
|
@ -441,48 +436,50 @@ int wxCheckedListCtrl::GetCheckedItemCount() const
|
|||
|
||||
// event handlers
|
||||
|
||||
void wxCheckedListCtrl::OnMouseEvent(wxMouseEvent& event)
|
||||
void wxCheckedListCtrl::OnMouseEvent(wxMouseEvent &event)
|
||||
{
|
||||
if (!event.LeftDown()) {
|
||||
event.Skip();
|
||||
if (!event.LeftDown())
|
||||
{
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int flags;
|
||||
long item = HitTest(event.GetPosition(), flags);
|
||||
if (item == wxNOT_FOUND || !IsEnabled(item)) {
|
||||
|
||||
if (item == wxNOT_FOUND || !IsEnabled(item))
|
||||
{
|
||||
// skip this item
|
||||
event.Skip();
|
||||
return;
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// user clicked exactly on the checkbox or on the item row ?
|
||||
bool processcheck = (flags & wxLIST_HITTEST_ONITEMICON) ||
|
||||
((GetWindowStyle() & wxCLC_CHECK_WHEN_SELECTING) &&
|
||||
(flags & wxLIST_HITTEST_ONITEM));
|
||||
|
||||
if (processcheck) {
|
||||
bool processcheck = (flags & wxLIST_HITTEST_ONITEMICON) ||
|
||||
((GetWindowStyle() & wxCLC_CHECK_WHEN_SELECTING) &&
|
||||
(flags & wxLIST_HITTEST_ONITEM));
|
||||
|
||||
if (processcheck)
|
||||
{
|
||||
wxListEvent ev(wxEVT_NULL, GetId());
|
||||
ev.m_itemIndex = item;
|
||||
ev.m_itemIndex = item;
|
||||
|
||||
// send the check event
|
||||
if (IsChecked(item)) {
|
||||
|
||||
if (IsChecked(item))
|
||||
{
|
||||
ev.SetEventType(wxEVT_COMMAND_LIST_ITEM_UNCHECKED);
|
||||
Check(item, FALSE);
|
||||
AddPendingEvent(ev);
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.SetEventType(wxEVT_COMMAND_LIST_ITEM_CHECKED);
|
||||
Check(item, TRUE);
|
||||
AddPendingEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
#endif // wxUSE_CHECKEDLISTCTRL
|
||||
#endif // wxUSE_CHECKEDLISTCTRL
|
||||
|
|
|
@ -5,129 +5,170 @@
|
|||
IMPLEMENT_DYNAMIC_CLASS(wxJoyKeyTextCtrl, wxKeyTextCtrl)
|
||||
|
||||
BEGIN_EVENT_TABLE(wxJoyKeyTextCtrl, wxKeyTextCtrl)
|
||||
EVT_SDLJOY(wxJoyKeyTextCtrl::OnJoy)
|
||||
EVT_SDLJOY(wxJoyKeyTextCtrl::OnJoy)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
int wxJoyKeyTextCtrl::DigitalButton(wxSDLJoyEvent &event)
|
||||
{
|
||||
int sdlval = event.GetControlValue();
|
||||
int sdltype = event.GetControlType();
|
||||
int sdlval = event.GetControlValue();
|
||||
int sdltype = event.GetControlType();
|
||||
|
||||
switch (sdltype)
|
||||
{
|
||||
case WXSDLJOY_AXIS:
|
||||
// for val = 0 return arbitrary direction; val means "off"
|
||||
return sdlval > 0 ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS;
|
||||
|
||||
case WXSDLJOY_HAT:
|
||||
|
||||
/* URDL = 1248 */
|
||||
switch (sdlval)
|
||||
{
|
||||
case 1:
|
||||
return WXJB_HAT_N;
|
||||
|
||||
case 2:
|
||||
return WXJB_HAT_E;
|
||||
|
||||
case 3:
|
||||
return WXJB_HAT_NE;
|
||||
|
||||
case 4:
|
||||
return WXJB_HAT_S;
|
||||
|
||||
case 6:
|
||||
return WXJB_HAT_SE;
|
||||
|
||||
case 8:
|
||||
return WXJB_HAT_W;
|
||||
|
||||
case 9:
|
||||
return WXJB_HAT_NW;
|
||||
|
||||
case 12:
|
||||
return WXJB_HAT_SW;
|
||||
|
||||
default:
|
||||
return WXJB_HAT_N; // arbitrary direction; val = 0 means "off"
|
||||
}
|
||||
|
||||
case WXSDLJOY_BUTTON:
|
||||
return WXJB_BUTTON;
|
||||
|
||||
switch(sdltype) {
|
||||
case WXSDLJOY_AXIS:
|
||||
// for val = 0 return arbitrary direction; val means "off"
|
||||
return sdlval > 0 ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS;
|
||||
case WXSDLJOY_HAT:
|
||||
/* URDL = 1248 */
|
||||
switch(sdlval) {
|
||||
case 1:
|
||||
return WXJB_HAT_N;
|
||||
case 2:
|
||||
return WXJB_HAT_E;
|
||||
case 3:
|
||||
return WXJB_HAT_NE;
|
||||
case 4:
|
||||
return WXJB_HAT_S;
|
||||
case 6:
|
||||
return WXJB_HAT_SE;
|
||||
case 8:
|
||||
return WXJB_HAT_W;
|
||||
case 9:
|
||||
return WXJB_HAT_NW;
|
||||
case 12:
|
||||
return WXJB_HAT_SW;
|
||||
default:
|
||||
return WXJB_HAT_N; // arbitrary direction; val = 0 means "off"
|
||||
// unknown ctrl type
|
||||
return -1;
|
||||
}
|
||||
case WXSDLJOY_BUTTON:
|
||||
return WXJB_BUTTON;
|
||||
default:
|
||||
// unknown ctrl type
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void wxJoyKeyTextCtrl::OnJoy(wxSDLJoyEvent &event)
|
||||
{
|
||||
short val = event.GetControlValue();
|
||||
int mod = DigitalButton(event);
|
||||
int key = event.GetControlIndex(), joy = event.GetJoy() + 1;
|
||||
short val = event.GetControlValue();
|
||||
int mod = DigitalButton(event);
|
||||
int key = event.GetControlIndex(), joy = event.GetJoy() + 1;
|
||||
|
||||
if(!val || mod < 0)
|
||||
return;
|
||||
wxString nv = ToString(mod, key, joy);
|
||||
if(nv.empty())
|
||||
return;
|
||||
if(multikey) {
|
||||
wxString ov = GetValue();
|
||||
if(!ov.empty())
|
||||
nv = ov + multikey + nv;
|
||||
}
|
||||
SetValue(nv);
|
||||
if(keyenter)
|
||||
Navigate();
|
||||
if (!val || mod < 0)
|
||||
return;
|
||||
|
||||
wxString nv = ToString(mod, key, joy);
|
||||
|
||||
if (nv.empty())
|
||||
return;
|
||||
|
||||
if (multikey)
|
||||
{
|
||||
wxString ov = GetValue();
|
||||
|
||||
if (!ov.empty())
|
||||
nv = ov + multikey + nv;
|
||||
}
|
||||
|
||||
SetValue(nv);
|
||||
|
||||
if (keyenter)
|
||||
Navigate();
|
||||
}
|
||||
|
||||
wxString wxJoyKeyTextCtrl::ToString(int mod, int key, int joy)
|
||||
{
|
||||
if(!joy)
|
||||
return wxKeyTextCtrl::ToString(mod, key);
|
||||
wxString s;
|
||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
s.Printf(_("Joy%d-"), joy);
|
||||
wxString mk;
|
||||
switch(mod) {
|
||||
case WXJB_AXIS_PLUS:
|
||||
mk.Printf(_("Axis%d+"), key);
|
||||
break;
|
||||
case WXJB_AXIS_MINUS:
|
||||
mk.Printf(_("Axis%d-"), key);
|
||||
break;
|
||||
case WXJB_BUTTON:
|
||||
mk.Printf(_("Button%d"), key);
|
||||
break;
|
||||
case WXJB_HAT_N:
|
||||
mk.Printf(_("Hat%dN"), key);
|
||||
break;
|
||||
case WXJB_HAT_S:
|
||||
mk.Printf(_("Hat%dS"), key);
|
||||
break;
|
||||
case WXJB_HAT_W:
|
||||
mk.Printf(_("Hat%dW"), key);
|
||||
break;
|
||||
case WXJB_HAT_E:
|
||||
mk.Printf(_("Hat%dE"), key);
|
||||
break;
|
||||
case WXJB_HAT_NW:
|
||||
mk.Printf(_("Hat%dNW"), key);
|
||||
break;
|
||||
case WXJB_HAT_NE:
|
||||
mk.Printf(_("Hat%dNE"), key);
|
||||
break;
|
||||
case WXJB_HAT_SW:
|
||||
mk.Printf(_("Hat%dSW"), key);
|
||||
break;
|
||||
case WXJB_HAT_SE:
|
||||
mk.Printf(_("Hat%dSE"), key);
|
||||
break;
|
||||
}
|
||||
s += mk;
|
||||
return s;
|
||||
if (!joy)
|
||||
return wxKeyTextCtrl::ToString(mod, key);
|
||||
|
||||
wxString s;
|
||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
s.Printf(_("Joy%d-"), joy);
|
||||
wxString mk;
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case WXJB_AXIS_PLUS:
|
||||
mk.Printf(_("Axis%d+"), key);
|
||||
break;
|
||||
|
||||
case WXJB_AXIS_MINUS:
|
||||
mk.Printf(_("Axis%d-"), key);
|
||||
break;
|
||||
|
||||
case WXJB_BUTTON:
|
||||
mk.Printf(_("Button%d"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_N:
|
||||
mk.Printf(_("Hat%dN"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_S:
|
||||
mk.Printf(_("Hat%dS"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_W:
|
||||
mk.Printf(_("Hat%dW"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_E:
|
||||
mk.Printf(_("Hat%dE"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_NW:
|
||||
mk.Printf(_("Hat%dNW"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_NE:
|
||||
mk.Printf(_("Hat%dNE"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_SW:
|
||||
mk.Printf(_("Hat%dSW"), key);
|
||||
break;
|
||||
|
||||
case WXJB_HAT_SE:
|
||||
mk.Printf(_("Hat%dSE"), key);
|
||||
break;
|
||||
}
|
||||
|
||||
s += mk;
|
||||
return s;
|
||||
}
|
||||
|
||||
wxString wxJoyKeyTextCtrl::ToString(wxJoyKeyBinding_v keys, wxChar sep)
|
||||
{
|
||||
wxString ret;
|
||||
for(int i = 0; i < keys.size(); i++) {
|
||||
if(i > 0)
|
||||
ret += sep;
|
||||
wxString key = ToString(keys[i].mod, keys[i].key, keys[i].joy);
|
||||
if(key.empty())
|
||||
return wxEmptyString;
|
||||
ret += key;
|
||||
}
|
||||
return ret;
|
||||
wxString ret;
|
||||
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ret += sep;
|
||||
|
||||
wxString key = ToString(keys[i].mod, keys[i].key, keys[i].joy);
|
||||
|
||||
if (key.empty())
|
||||
return wxEmptyString;
|
||||
|
||||
ret += key;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include <wx/regex.h>
|
||||
|
@ -136,137 +177,168 @@ wxString wxJoyKeyTextCtrl::ToString(wxJoyKeyBinding_v keys, wxChar sep)
|
|||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
// \1 is joy #
|
||||
static wxRegEx joyre(_("^Joy([0-9]+)[-+]"), wxRE_EXTENDED|wxRE_ICASE);
|
||||
static wxRegEx joyre(_("^Joy([0-9]+)[-+]"), wxRE_EXTENDED | wxRE_ICASE);
|
||||
// \1 is axis# and \2 is + or -
|
||||
static wxRegEx axre(_("Axis([0-9]+)([+-])"), wxRE_EXTENDED|wxRE_ICASE);
|
||||
static wxRegEx axre(_("Axis([0-9]+)([+-])"), wxRE_EXTENDED | wxRE_ICASE);
|
||||
// \1 is button#
|
||||
static wxRegEx butre(_("Button([0-9]+)"), wxRE_EXTENDED|wxRE_ICASE);
|
||||
static wxRegEx butre(_("Button([0-9]+)"), wxRE_EXTENDED | wxRE_ICASE);
|
||||
// \1 is hat#, \3 is N, \4 is S, \5 is E, \6 is W, \7 is NE, \8 is SE,
|
||||
// \9 is SW, \10 is NW
|
||||
static wxRegEx hatre(_("Hat([0-9]+)((N|North|U|Up)|(S|South|D|Down)|"
|
||||
"(E|East|R|Right)|(W|West|L|Left)|"
|
||||
"(NE|NorthEast|UR|UpRight)|(SE|SouthEast|DR|DownRight)|"
|
||||
"(SW|SouthWest|DL|DownLeft)|(NW|NorthWest|UL|UpLeft))"),
|
||||
wxRE_EXTENDED|wxRE_ICASE);
|
||||
"(E|East|R|Right)|(W|West|L|Left)|"
|
||||
"(NE|NorthEast|UR|UpRight)|(SE|SouthEast|DR|DownRight)|"
|
||||
"(SW|SouthWest|DL|DownLeft)|(NW|NorthWest|UL|UpLeft))"),
|
||||
wxRE_EXTENDED | wxRE_ICASE);
|
||||
// use of static wxRegeEx is not thread-safe
|
||||
static wxCriticalSection recs;
|
||||
|
||||
// wx provides no atoi for wxChar
|
||||
// this is not a universal function; assumes valid number
|
||||
static int simple_atoi(const wxChar *s, int len)
|
||||
static int simple_atoi(const wxChar* s, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
for(int i = 0; i < len; i++)
|
||||
ret = ret * 10 + s[i] - wxT('0');
|
||||
return ret;
|
||||
int ret = 0;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
ret = ret * 10 + s[i] - wxT('0');
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ParseJoy(const wxChar *s, int len, int &mod, int &key, int &joy)
|
||||
static bool ParseJoy(const wxChar* s, int len, int &mod, int &key, int &joy)
|
||||
{
|
||||
mod = key = joy = 0;
|
||||
if(!len)
|
||||
return false;
|
||||
mod = key = joy = 0;
|
||||
|
||||
wxCriticalSectionLocker lk(recs);
|
||||
size_t b, l;
|
||||
if(!joyre.Matches(s) || !joyre.GetMatch(&b, &l) || b)
|
||||
return false;
|
||||
const wxChar *p = s + l;
|
||||
int alen = len - l;
|
||||
joyre.GetMatch(&b, &l, 1);
|
||||
joy = simple_atoi(s + b, l);
|
||||
if (!len)
|
||||
return false;
|
||||
|
||||
wxCriticalSectionLocker lk(recs);
|
||||
size_t b, l;
|
||||
|
||||
if (!joyre.Matches(s) || !joyre.GetMatch(&b, &l) || b)
|
||||
return false;
|
||||
|
||||
const wxChar* p = s + l;
|
||||
int alen = len - l;
|
||||
joyre.GetMatch(&b, &l, 1);
|
||||
joy = simple_atoi(s + b, l);
|
||||
#define is_ctrl(re) re.Matches(p) && re.GetMatch(&b, &l) && l == alen && !b
|
||||
if(is_ctrl(axre)) {
|
||||
axre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
axre.GetMatch(&b, &l, 2);
|
||||
mod = p[b] == wxT('+') ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS;
|
||||
} else if(is_ctrl(butre)) {
|
||||
butre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
mod = WXJB_BUTTON;
|
||||
} else if(is_ctrl(hatre)) {
|
||||
hatre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
|
||||
if (is_ctrl(axre))
|
||||
{
|
||||
axre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
axre.GetMatch(&b, &l, 2);
|
||||
mod = p[b] == wxT('+') ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS;
|
||||
}
|
||||
else if (is_ctrl(butre))
|
||||
{
|
||||
butre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
mod = WXJB_BUTTON;
|
||||
}
|
||||
else if (is_ctrl(hatre))
|
||||
{
|
||||
hatre.GetMatch(&b, &l, 1);
|
||||
key = simple_atoi(p + b, l);
|
||||
#define check_dir(n, d) else if(hatre.GetMatch(&b, &l, n) && l > 0) mod = WXJB_HAT_##d
|
||||
if(0);
|
||||
check_dir(3, N);
|
||||
check_dir(4, S);
|
||||
check_dir(5, E);
|
||||
check_dir(6, W);
|
||||
check_dir(7, NE);
|
||||
check_dir(8, SE);
|
||||
check_dir(9, SW);
|
||||
check_dir(10, NW);
|
||||
} else {
|
||||
joy = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (0);
|
||||
|
||||
check_dir(3, N);
|
||||
check_dir(4, S);
|
||||
check_dir(5, E);
|
||||
check_dir(6, W);
|
||||
check_dir(7, NE);
|
||||
check_dir(8, SE);
|
||||
check_dir(9, SW);
|
||||
check_dir(10, NW);
|
||||
}
|
||||
else
|
||||
{
|
||||
joy = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxJoyKeyTextCtrl::ParseString(const wxChar *s, int len, int &mod, int &key, int &joy)
|
||||
bool wxJoyKeyTextCtrl::ParseString(const wxChar* s, int len, int &mod, int &key, int &joy)
|
||||
{
|
||||
if(ParseJoy(s, len, mod, key, joy))
|
||||
return true;
|
||||
return wxKeyTextCtrl::ParseString(s, len, mod, key);
|
||||
if (ParseJoy(s, len, mod, key, joy))
|
||||
return true;
|
||||
|
||||
return wxKeyTextCtrl::ParseString(s, len, mod, key);
|
||||
}
|
||||
|
||||
bool wxJoyKeyTextCtrl::FromString(const wxString &s, int &mod, int &key, int &joy)
|
||||
{
|
||||
return ParseString(s.c_str(), s.size(), mod, key, joy);
|
||||
return ParseString(s.c_str(), s.size(), mod, key, joy);
|
||||
}
|
||||
|
||||
wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString &s, wxChar sep)
|
||||
{
|
||||
wxJoyKeyBinding_v ret, empty;
|
||||
int mod, key, joy;
|
||||
int len = s.size();
|
||||
if(!len)
|
||||
return empty;
|
||||
wxJoyKeyBinding_v ret, empty;
|
||||
int mod, key, joy;
|
||||
int len = s.size();
|
||||
|
||||
for(int lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--) {
|
||||
if(lastkey == len - 1) {
|
||||
// sep as accel
|
||||
if(!lastkey)
|
||||
break;
|
||||
if(s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') ||
|
||||
s[lastkey - 1] == sep)
|
||||
continue;
|
||||
if (!len)
|
||||
return empty;
|
||||
|
||||
for (int lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--)
|
||||
{
|
||||
if (lastkey == len - 1)
|
||||
{
|
||||
// sep as accel
|
||||
if (!lastkey)
|
||||
break;
|
||||
|
||||
if (s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') ||
|
||||
s[lastkey - 1] == sep)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key, joy))
|
||||
return empty;
|
||||
|
||||
wxJoyKeyBinding jb = { key, mod, joy };
|
||||
ret.insert(ret.begin(), jb);
|
||||
len = lastkey;
|
||||
}
|
||||
if(!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key, joy))
|
||||
return empty;
|
||||
|
||||
if (!ParseString(s.c_str(), len, mod, key, joy))
|
||||
return empty;
|
||||
|
||||
wxJoyKeyBinding jb = { key, mod, joy };
|
||||
ret.insert(ret.begin(), jb);
|
||||
len = lastkey;
|
||||
}
|
||||
if(!ParseString(s.c_str(), len, mod, key, joy))
|
||||
return empty;
|
||||
wxJoyKeyBinding jb = { key, mod, joy };
|
||||
ret.insert(ret.begin(), jb);
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(wxJoyKeyValidator, wxValidator)
|
||||
|
||||
bool wxJoyKeyValidator::TransferToWindow()
|
||||
{
|
||||
if(!val)
|
||||
return false;
|
||||
wxJoyKeyTextCtrl *jk = wxDynamicCast(GetWindow(), wxJoyKeyTextCtrl);
|
||||
if(!jk)
|
||||
return false;
|
||||
jk->SetValue(wxJoyKeyTextCtrl::ToString(*val));
|
||||
return true;
|
||||
if (!val)
|
||||
return false;
|
||||
|
||||
wxJoyKeyTextCtrl* jk = wxDynamicCast(GetWindow(), wxJoyKeyTextCtrl);
|
||||
|
||||
if (!jk)
|
||||
return false;
|
||||
|
||||
jk->SetValue(wxJoyKeyTextCtrl::ToString(*val));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxJoyKeyValidator::TransferFromWindow()
|
||||
{
|
||||
if(!val)
|
||||
return false;
|
||||
wxJoyKeyTextCtrl *jk = wxDynamicCast(GetWindow(), wxJoyKeyTextCtrl);
|
||||
if(!jk)
|
||||
return false;
|
||||
*val = wxJoyKeyTextCtrl::FromString(jk->GetValue());
|
||||
return true;
|
||||
if (!val)
|
||||
return false;
|
||||
|
||||
wxJoyKeyTextCtrl* jk = wxDynamicCast(GetWindow(), wxJoyKeyTextCtrl);
|
||||
|
||||
if (!jk)
|
||||
return false;
|
||||
|
||||
*val = wxJoyKeyTextCtrl::FromString(jk->GetValue());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,226 +3,280 @@
|
|||
IMPLEMENT_DYNAMIC_CLASS(wxKeyTextCtrl, wxTextCtrl)
|
||||
|
||||
BEGIN_EVENT_TABLE(wxKeyTextCtrl, wxTextCtrl)
|
||||
EVT_KEY_DOWN(wxKeyTextCtrl::OnKeyDown)
|
||||
EVT_KEY_UP(wxKeyTextCtrl::OnKeyUp)
|
||||
EVT_KEY_DOWN(wxKeyTextCtrl::OnKeyDown)
|
||||
EVT_KEY_UP(wxKeyTextCtrl::OnKeyUp)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
void wxKeyTextCtrl::OnKeyDown(wxKeyEvent &event)
|
||||
{
|
||||
lastmod = event.GetModifiers();
|
||||
lastkey = event.GetKeyCode();
|
||||
lastmod = event.GetModifiers();
|
||||
lastkey = event.GetKeyCode();
|
||||
}
|
||||
|
||||
void wxKeyTextCtrl::OnKeyUp(wxKeyEvent &event)
|
||||
{
|
||||
int mod = lastmod;
|
||||
int key = lastkey;
|
||||
lastmod = lastkey = 0;
|
||||
// key is only 0 if we missed the keydown event
|
||||
// or if we are being shipped pseudo keypress events
|
||||
// either way, just ignore
|
||||
if(!key)
|
||||
return;
|
||||
// use unmodified backspace to clear last key, if enabled
|
||||
// if blank or backspace is modified, add normally instead
|
||||
if(clearable && !mod && key == WXK_BACK && !GetValue().empty())
|
||||
{
|
||||
wxString val = GetValue();
|
||||
int lastkey = val.rfind(multikey);
|
||||
if(lastkey && lastkey != wxString::npos) {
|
||||
// if this was actually a ,-accel, delete instead
|
||||
if(lastkey == val.size() - 1) {
|
||||
lastkey = val.rfind(multikey, lastkey-1);
|
||||
if(lastkey == wxString::npos)
|
||||
lastkey = 0;
|
||||
}
|
||||
val.resize(lastkey);
|
||||
SetValue(val);
|
||||
} else
|
||||
Clear();
|
||||
} else {
|
||||
wxString nv = ToString(mod, key);
|
||||
if(nv.empty())
|
||||
return;
|
||||
if(multikey) {
|
||||
wxString ov = GetValue();
|
||||
if(!ov.empty())
|
||||
nv = ov + multikey + nv;
|
||||
int mod = lastmod;
|
||||
int key = lastkey;
|
||||
lastmod = lastkey = 0;
|
||||
|
||||
// key is only 0 if we missed the keydown event
|
||||
// or if we are being shipped pseudo keypress events
|
||||
// either way, just ignore
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
// use unmodified backspace to clear last key, if enabled
|
||||
// if blank or backspace is modified, add normally instead
|
||||
if (clearable && !mod && key == WXK_BACK && !GetValue().empty())
|
||||
{
|
||||
wxString val = GetValue();
|
||||
int lastkey = val.rfind(multikey);
|
||||
|
||||
if (lastkey && lastkey != wxString::npos)
|
||||
{
|
||||
// if this was actually a ,-accel, delete instead
|
||||
if (lastkey == val.size() - 1)
|
||||
{
|
||||
lastkey = val.rfind(multikey, lastkey - 1);
|
||||
|
||||
if (lastkey == wxString::npos)
|
||||
lastkey = 0;
|
||||
}
|
||||
|
||||
val.resize(lastkey);
|
||||
SetValue(val);
|
||||
}
|
||||
else
|
||||
Clear();
|
||||
}
|
||||
SetValue(nv);
|
||||
}
|
||||
if(keyenter)
|
||||
Navigate();
|
||||
else
|
||||
{
|
||||
wxString nv = ToString(mod, key);
|
||||
|
||||
if (nv.empty())
|
||||
return;
|
||||
|
||||
if (multikey)
|
||||
{
|
||||
wxString ov = GetValue();
|
||||
|
||||
if (!ov.empty())
|
||||
nv = ov + multikey + nv;
|
||||
}
|
||||
|
||||
SetValue(nv);
|
||||
}
|
||||
|
||||
if (keyenter)
|
||||
Navigate();
|
||||
}
|
||||
|
||||
wxString wxKeyTextCtrl::ToString(int mod, int key)
|
||||
{
|
||||
// wx ignores non-alnum printable chars
|
||||
// actually, wx gives an assertion error, so it's best to filter out
|
||||
// before passing to ToString()
|
||||
bool char_override = key > 32 && key < WXK_START && !wxIsalnum(key);
|
||||
// wx also ignores modifiers (and does not report meta at all)
|
||||
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT;
|
||||
wxAcceleratorEntry ae(mod, char_override || mod_override ? WXK_F1 : key);
|
||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
wxString s = ae.ToString();
|
||||
if(char_override || mod_override) {
|
||||
int l = s.rfind(wxT('-'));
|
||||
if(l == wxString::npos)
|
||||
l = 0;
|
||||
else l++;
|
||||
s.erase(l);
|
||||
switch(key) {
|
||||
case WXK_SHIFT:
|
||||
s.append(_("SHIFT"));
|
||||
break;
|
||||
case WXK_ALT:
|
||||
s.append(_("ALT"));
|
||||
break;
|
||||
case WXK_CONTROL:
|
||||
s.append(_("CTRL"));
|
||||
break;
|
||||
default:
|
||||
s.append((wxChar)key);
|
||||
}
|
||||
}
|
||||
// wx ignores non-alnum printable chars
|
||||
// actually, wx gives an assertion error, so it's best to filter out
|
||||
// before passing to ToString()
|
||||
bool char_override = key > 32 && key < WXK_START && !wxIsalnum(key);
|
||||
// wx also ignores modifiers (and does not report meta at all)
|
||||
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT;
|
||||
wxAcceleratorEntry ae(mod, char_override || mod_override ? WXK_F1 : key);
|
||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
wxString s = ae.ToString();
|
||||
|
||||
// on Mac, ctrl/meta become xctrl/cmd
|
||||
// on other, meta is ignored
|
||||
if (char_override || mod_override)
|
||||
{
|
||||
int l = s.rfind(wxT('-'));
|
||||
|
||||
if (l == wxString::npos)
|
||||
l = 0;
|
||||
else l++;
|
||||
|
||||
s.erase(l);
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case WXK_SHIFT:
|
||||
s.append(_("SHIFT"));
|
||||
break;
|
||||
|
||||
case WXK_ALT:
|
||||
s.append(_("ALT"));
|
||||
break;
|
||||
|
||||
case WXK_CONTROL:
|
||||
s.append(_("CTRL"));
|
||||
break;
|
||||
|
||||
default:
|
||||
s.append((wxChar)key);
|
||||
}
|
||||
}
|
||||
|
||||
// on Mac, ctrl/meta become xctrl/cmd
|
||||
// on other, meta is ignored
|
||||
#ifndef __WXMAC__
|
||||
if(mod & wxMOD_META) {
|
||||
s.insert(0, _("Meta-"));
|
||||
}
|
||||
|
||||
if (mod & wxMOD_META)
|
||||
{
|
||||
s.insert(0, _("Meta-"));
|
||||
}
|
||||
|
||||
#endif
|
||||
if(s.empty() || (key != wxT('-') && s[s.size()-1] == wxT('-')))
|
||||
// bad key combo; probably also generates an assertion in wx
|
||||
return wxEmptyString;
|
||||
return s;
|
||||
|
||||
if (s.empty() || (key != wxT('-') && s[s.size() - 1] == wxT('-')))
|
||||
// bad key combo; probably also generates an assertion in wx
|
||||
return wxEmptyString;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep)
|
||||
{
|
||||
wxString ret;
|
||||
for(int i = 0; i < keys.size(); i++) {
|
||||
if(i > 0)
|
||||
ret += sep;
|
||||
wxString key = ToString(keys[i].GetFlags(), keys[i].GetKeyCode());
|
||||
if(key.empty())
|
||||
return wxEmptyString;
|
||||
ret += key;
|
||||
}
|
||||
return ret;
|
||||
wxString ret;
|
||||
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ret += sep;
|
||||
|
||||
wxString key = ToString(keys[i].GetFlags(), keys[i].GetKeyCode());
|
||||
|
||||
if (key.empty())
|
||||
return wxEmptyString;
|
||||
|
||||
ret += key;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wxKeyTextCtrl::ParseString(const wxChar *s, int len, int &mod, int &key)
|
||||
bool wxKeyTextCtrl::ParseString(const wxChar* s, int len, int &mod, int &key)
|
||||
{
|
||||
mod = key = 0;
|
||||
if(!s || !len)
|
||||
return false;
|
||||
wxString a = wxT('\t');
|
||||
a.append(s, len);
|
||||
wxAcceleratorEntry ae;
|
||||
mod = key = 0;
|
||||
|
||||
if (!s || !len)
|
||||
return false;
|
||||
|
||||
wxString a = wxT('\t');
|
||||
a.append(s, len);
|
||||
wxAcceleratorEntry ae;
|
||||
#ifndef __WXMAC__
|
||||
#define check_meta(str) do { \
|
||||
wxString meta = str; \
|
||||
for(int ml = 0; (ml = a.find(meta, ml)) != wxString::npos; ml++) { \
|
||||
if(!ml || a[ml-1] == wxT('-') || a[ml-1] == wxT('+')) { \
|
||||
mod |= wxMOD_META; \
|
||||
a.erase(ml, meta.size()); \
|
||||
ml = -1; \
|
||||
} \
|
||||
if(!ml || a[ml-1] == wxT('-') || a[ml-1] == wxT('+')) { \
|
||||
mod |= wxMOD_META; \
|
||||
a.erase(ml, meta.size()); \
|
||||
ml = -1; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
check_meta(wxT("Meta-"));
|
||||
check_meta(wxT("Meta+"));
|
||||
check_meta(_("Meta-"));
|
||||
check_meta(_("Meta+"));
|
||||
check_meta(wxT("Meta-"));
|
||||
check_meta(wxT("Meta+"));
|
||||
check_meta(_("Meta-"));
|
||||
check_meta(_("Meta+"));
|
||||
#endif
|
||||
// wx disallows standalone modifiers
|
||||
// unlike ToString(), this generates a debug message rather than
|
||||
// an assertion error, so it's easy to ignore and expensive to avoid
|
||||
// beforehand. Instead, check for them on failure
|
||||
if(!ae.FromString(a)) {
|
||||
a.MakeUpper();
|
||||
|
||||
// wx disallows standalone modifiers
|
||||
// unlike ToString(), this generates a debug message rather than
|
||||
// an assertion error, so it's easy to ignore and expensive to avoid
|
||||
// beforehand. Instead, check for them on failure
|
||||
if (!ae.FromString(a))
|
||||
{
|
||||
a.MakeUpper();
|
||||
#define chk_str(n, k) do { \
|
||||
wxString t = n; \
|
||||
if(a.size() > t.size() && a.substr(a.size() - t.size()) == t) { \
|
||||
a.replace(a.size() - t.size(), t.size(), wxT("F1")); \
|
||||
wxString ss(s); \
|
||||
if(ae.FromString(a)) { \
|
||||
mod |= ae.GetFlags(); \
|
||||
key = k; \
|
||||
return true; \
|
||||
} \
|
||||
a.replace(a.size() - 2, 2, n); \
|
||||
a.replace(a.size() - t.size(), t.size(), wxT("F1")); \
|
||||
wxString ss(s); \
|
||||
if(ae.FromString(a)) { \
|
||||
mod |= ae.GetFlags(); \
|
||||
key = k; \
|
||||
return true; \
|
||||
} \
|
||||
a.replace(a.size() - 2, 2, n); \
|
||||
} \
|
||||
} while(0)
|
||||
chk_str(wxT("ALT"), WXK_ALT);
|
||||
chk_str(wxT("SHIFT"), WXK_SHIFT);
|
||||
chk_str(wxT("CTRL"), WXK_CONTROL);
|
||||
chk_str(wxT("CONTROL"), WXK_CONTROL);
|
||||
chk_str(_("ALT"), WXK_ALT);
|
||||
chk_str(_("SHIFT"), WXK_SHIFT);
|
||||
chk_str(_("CTRL"), WXK_CONTROL);
|
||||
chk_str(_("CONTROL"), WXK_CONTROL);
|
||||
return false;
|
||||
}
|
||||
mod |= ae.GetFlags();
|
||||
key = ae.GetKeyCode();
|
||||
// wx makes key lower-case, but key events return upper case
|
||||
if(key < WXK_START && wxIslower(key))
|
||||
key = wxToupper(key);
|
||||
return true;
|
||||
chk_str(wxT("ALT"), WXK_ALT);
|
||||
chk_str(wxT("SHIFT"), WXK_SHIFT);
|
||||
chk_str(wxT("CTRL"), WXK_CONTROL);
|
||||
chk_str(wxT("CONTROL"), WXK_CONTROL);
|
||||
chk_str(_("ALT"), WXK_ALT);
|
||||
chk_str(_("SHIFT"), WXK_SHIFT);
|
||||
chk_str(_("CTRL"), WXK_CONTROL);
|
||||
chk_str(_("CONTROL"), WXK_CONTROL);
|
||||
return false;
|
||||
}
|
||||
|
||||
mod |= ae.GetFlags();
|
||||
key = ae.GetKeyCode();
|
||||
|
||||
// wx makes key lower-case, but key events return upper case
|
||||
if (key < WXK_START && wxIslower(key))
|
||||
key = wxToupper(key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxKeyTextCtrl::FromString(const wxString &s, int &mod, int &key)
|
||||
{
|
||||
return ParseString(s.c_str(), s.size(), mod, key);
|
||||
return ParseString(s.c_str(), s.size(), mod, key);
|
||||
}
|
||||
|
||||
wxAcceleratorEntry_v wxKeyTextCtrl::FromString(const wxString &s, wxChar sep)
|
||||
{
|
||||
wxAcceleratorEntry_v ret, empty;
|
||||
int mod, key;
|
||||
int len = s.size();
|
||||
wxAcceleratorEntry_v ret, empty;
|
||||
int mod, key;
|
||||
int len = s.size();
|
||||
|
||||
for(int lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--) {
|
||||
if(lastkey == len - 1) {
|
||||
// sep as accel
|
||||
if(!lastkey)
|
||||
break;
|
||||
if(s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') ||
|
||||
s[lastkey - 1] == sep)
|
||||
continue;
|
||||
for (int lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--)
|
||||
{
|
||||
if (lastkey == len - 1)
|
||||
{
|
||||
// sep as accel
|
||||
if (!lastkey)
|
||||
break;
|
||||
|
||||
if (s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') ||
|
||||
s[lastkey - 1] == sep)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key))
|
||||
return empty;
|
||||
|
||||
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
|
||||
len = lastkey;
|
||||
}
|
||||
if(!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key))
|
||||
return empty;
|
||||
|
||||
if (!ParseString(s.c_str(), len, mod, key))
|
||||
return empty;
|
||||
|
||||
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
|
||||
len = lastkey;
|
||||
}
|
||||
if(!ParseString(s.c_str(), len, mod, key))
|
||||
return empty;
|
||||
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(wxKeyValidator, wxValidator)
|
||||
|
||||
bool wxKeyValidator::TransferToWindow()
|
||||
{
|
||||
wxKeyTextCtrl *k = wxDynamicCast(GetWindow(), wxKeyTextCtrl);
|
||||
if(!k)
|
||||
return false;
|
||||
k->SetValue(wxKeyTextCtrl::ToString(*val));
|
||||
return true;
|
||||
wxKeyTextCtrl* k = wxDynamicCast(GetWindow(), wxKeyTextCtrl);
|
||||
|
||||
if (!k)
|
||||
return false;
|
||||
|
||||
k->SetValue(wxKeyTextCtrl::ToString(*val));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxKeyValidator::TransferFromWindow()
|
||||
{
|
||||
wxKeyTextCtrl *k = wxDynamicCast(GetWindow(), wxKeyTextCtrl);
|
||||
if(!k)
|
||||
return false;
|
||||
*val = wxKeyTextCtrl::FromString(k->GetValue());
|
||||
return true;
|
||||
wxKeyTextCtrl* k = wxDynamicCast(GetWindow(), wxKeyTextCtrl);
|
||||
|
||||
if (!k)
|
||||
return false;
|
||||
|
||||
*val = wxKeyTextCtrl::FromString(k->GetValue());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5,155 +5,196 @@
|
|||
|
||||
DEFINE_EVENT_TYPE(wxEVT_SDLJOY)
|
||||
|
||||
struct wxSDLJoyState {
|
||||
SDL_Joystick *dev;
|
||||
int nax, nhat, nbut;
|
||||
short *curval;
|
||||
~wxSDLJoyState() { if(dev) SDL_JoystickClose(dev); }
|
||||
struct wxSDLJoyState
|
||||
{
|
||||
SDL_Joystick* dev;
|
||||
int nax, nhat, nbut;
|
||||
short* curval;
|
||||
~wxSDLJoyState() { if (dev) SDL_JoystickClose(dev); }
|
||||
};
|
||||
|
||||
wxSDLJoy::wxSDLJoy(bool analog) : wxTimer(), digital(!analog),
|
||||
evthandler(0), joystate(0), nosticks(true)
|
||||
evthandler(0), joystate(0), nosticks(true)
|
||||
{
|
||||
// Start up joystick if not already started
|
||||
// FIXME: check for errors
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
// but we'll have to manage it manually
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
// now query joystick config and open joysticks
|
||||
// there is no way to reread this later (e.g. if joystick plugged in),
|
||||
// since SDL won't
|
||||
njoy = SDL_NumJoysticks();
|
||||
if(!njoy)
|
||||
return;
|
||||
joystate = new wxSDLJoyState_t[njoy];
|
||||
memset(joystate, 0, njoy * sizeof(*joystate));
|
||||
for(int i = 0; i < njoy; i++) {
|
||||
SDL_Joystick *dev = joystate[i].dev = SDL_JoystickOpen(i);
|
||||
int nctrl = 0;
|
||||
nctrl += joystate[i].nax = SDL_JoystickNumAxes(dev);
|
||||
nctrl += joystate[i].nhat = SDL_JoystickNumHats(dev);
|
||||
nctrl += joystate[i].nbut = SDL_JoystickNumButtons(dev);
|
||||
joystate[i].curval = new short[nctrl];
|
||||
memset(joystate[i].curval, 0, sizeof(short) * nctrl);
|
||||
}
|
||||
// Start up joystick if not already started
|
||||
// FIXME: check for errors
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
// but we'll have to manage it manually
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
// now query joystick config and open joysticks
|
||||
// there is no way to reread this later (e.g. if joystick plugged in),
|
||||
// since SDL won't
|
||||
njoy = SDL_NumJoysticks();
|
||||
|
||||
if (!njoy)
|
||||
return;
|
||||
|
||||
joystate = new wxSDLJoyState_t[njoy];
|
||||
memset(joystate, 0, njoy * sizeof(*joystate));
|
||||
|
||||
for (int i = 0; i < njoy; i++)
|
||||
{
|
||||
SDL_Joystick* dev = joystate[i].dev = SDL_JoystickOpen(i);
|
||||
int nctrl = 0;
|
||||
nctrl += joystate[i].nax = SDL_JoystickNumAxes(dev);
|
||||
nctrl += joystate[i].nhat = SDL_JoystickNumHats(dev);
|
||||
nctrl += joystate[i].nbut = SDL_JoystickNumButtons(dev);
|
||||
joystate[i].curval = new short[nctrl];
|
||||
memset(joystate[i].curval, 0, sizeof(short) * nctrl);
|
||||
}
|
||||
}
|
||||
|
||||
wxSDLJoy::~wxSDLJoy()
|
||||
{
|
||||
delete[] joystate;
|
||||
// SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
delete[] joystate;
|
||||
// SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
|
||||
wxEvtHandler *wxSDLJoy::Attach(wxEvtHandler *handler)
|
||||
wxEvtHandler* wxSDLJoy::Attach(wxEvtHandler* handler)
|
||||
{
|
||||
wxEvtHandler *prev = evthandler;
|
||||
evthandler = handler;
|
||||
return prev;
|
||||
wxEvtHandler* prev = evthandler;
|
||||
evthandler = handler;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void wxSDLJoy::Add(int joy)
|
||||
{
|
||||
if(joy >= njoy || !njoy)
|
||||
return;
|
||||
if(joy < 0) {
|
||||
for(int i = 0; i < njoy; i++)
|
||||
Add(i);
|
||||
return;
|
||||
}
|
||||
if(!joystate[joy].dev)
|
||||
joystate[joy].dev = SDL_JoystickOpen(joy);
|
||||
if(nosticks && joystate[joy].dev) {
|
||||
Start(50);
|
||||
nosticks = false;
|
||||
}
|
||||
if (joy >= njoy || !njoy)
|
||||
return;
|
||||
|
||||
if (joy < 0)
|
||||
{
|
||||
for (int i = 0; i < njoy; i++)
|
||||
Add(i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!joystate[joy].dev)
|
||||
joystate[joy].dev = SDL_JoystickOpen(joy);
|
||||
|
||||
if (nosticks && joystate[joy].dev)
|
||||
{
|
||||
Start(50);
|
||||
nosticks = false;
|
||||
}
|
||||
}
|
||||
|
||||
void wxSDLJoy::Remove(int joy)
|
||||
{
|
||||
if(joy >= njoy || !njoy)
|
||||
return;
|
||||
if(joy < 0) {
|
||||
for(int i = 0; i < njoy; i++)
|
||||
if(joystate[i].dev) {
|
||||
SDL_JoystickClose(joystate[i].dev);
|
||||
joystate[i].dev = NULL;
|
||||
}
|
||||
if (joy >= njoy || !njoy)
|
||||
return;
|
||||
|
||||
if (joy < 0)
|
||||
{
|
||||
for (int i = 0; i < njoy; i++)
|
||||
if (joystate[i].dev)
|
||||
{
|
||||
SDL_JoystickClose(joystate[i].dev);
|
||||
joystate[i].dev = NULL;
|
||||
}
|
||||
|
||||
Stop();
|
||||
nosticks = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!joystate[joy].dev)
|
||||
return;
|
||||
|
||||
SDL_JoystickClose(joystate[joy].dev);
|
||||
joystate[joy].dev = NULL;
|
||||
|
||||
for (int i = 0; i < njoy; i++)
|
||||
if (joystate[i].dev)
|
||||
return;
|
||||
|
||||
Stop();
|
||||
nosticks = true;
|
||||
return;
|
||||
}
|
||||
if(!joystate[joy].dev)
|
||||
return;
|
||||
SDL_JoystickClose(joystate[joy].dev);
|
||||
joystate[joy].dev = NULL;
|
||||
for(int i = 0; i < njoy; i++)
|
||||
if(joystate[i].dev)
|
||||
return;
|
||||
Stop();
|
||||
nosticks = true;
|
||||
}
|
||||
|
||||
void wxSDLJoy::Notify()
|
||||
{
|
||||
if(nosticks)
|
||||
return;
|
||||
SDL_JoystickUpdate();
|
||||
wxEvtHandler *handler = evthandler ? evthandler : wxWindow::FindFocus();
|
||||
for(int i = 0; i < njoy; i++) {
|
||||
SDL_Joystick *dev = joystate[i].dev;
|
||||
if(dev) {
|
||||
int nax = joystate[i].nax, nhat = joystate[i].nhat,
|
||||
nbut = joystate[i].nbut;
|
||||
int ctrl = 0;
|
||||
short val;
|
||||
for(int j = 0; j < nax; j++) {
|
||||
val = SDL_JoystickGetAxis(dev, j);
|
||||
if(digital) {
|
||||
if(val > 0x3fff)
|
||||
val = 0x7fff;
|
||||
else if(val <= -0x3fff)
|
||||
val = -0x7fff;
|
||||
else
|
||||
val = 0;
|
||||
if (nosticks)
|
||||
return;
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
wxEvtHandler* handler = evthandler ? evthandler : wxWindow::FindFocus();
|
||||
|
||||
for (int i = 0; i < njoy; i++)
|
||||
{
|
||||
SDL_Joystick* dev = joystate[i].dev;
|
||||
|
||||
if (dev)
|
||||
{
|
||||
int nax = joystate[i].nax, nhat = joystate[i].nhat,
|
||||
nbut = joystate[i].nbut;
|
||||
int ctrl = 0;
|
||||
short val;
|
||||
|
||||
for (int j = 0; j < nax; j++)
|
||||
{
|
||||
val = SDL_JoystickGetAxis(dev, j);
|
||||
|
||||
if (digital)
|
||||
{
|
||||
if (val > 0x3fff)
|
||||
val = 0x7fff;
|
||||
else if (val <= -0x3fff)
|
||||
val = -0x7fff;
|
||||
else
|
||||
val = 0;
|
||||
}
|
||||
|
||||
if (handler && val != joystate[i].curval[j])
|
||||
{
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
joystate[i].curval[j] = val;
|
||||
}
|
||||
|
||||
for (int j = 0; j < nhat; j++)
|
||||
{
|
||||
val = SDL_JoystickGetHat(dev, j);
|
||||
|
||||
if (handler && val != joystate[i].curval[nax + j])
|
||||
{
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_HAT;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[nax + j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
joystate[i].curval[nax + j] = val;
|
||||
}
|
||||
|
||||
for (int j = 0; j < nbut; j++)
|
||||
{
|
||||
val = SDL_JoystickGetButton(dev, j);
|
||||
|
||||
if (handler && val != joystate[i].curval[nax + nhat + j])
|
||||
{
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[nax + nhat + j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
joystate[i].curval[nax + nhat + j] = val;
|
||||
}
|
||||
}
|
||||
if(handler && val != joystate[i].curval[j]) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
joystate[i].curval[j] = val;
|
||||
}
|
||||
for(int j = 0; j < nhat; j++) {
|
||||
val = SDL_JoystickGetHat(dev, j);
|
||||
if(handler && val != joystate[i].curval[nax + j]) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_HAT;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[nax + j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
joystate[i].curval[nax + j] = val;
|
||||
}
|
||||
for(int j = 0; j < nbut; j++) {
|
||||
val = SDL_JoystickGetButton(dev, j);
|
||||
if(handler && val != joystate[i].curval[nax + nhat + j]) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY, GetId());
|
||||
ev.joy = i;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = j;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = joystate[i].curval[nax + nhat + j];
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
joystate[i].curval[nax + nhat + j] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,25 +14,25 @@
|
|||
#define _WX_CHECKEDLISTCTRL_H_
|
||||
|
||||
// wxWidgets headers
|
||||
#include "wx/webupdatedef.h" // for the WXDLLIMPEXP_WEBUPDATE macro
|
||||
#include "wx/webupdatedef.h" // for the WXDLLIMPEXP_WEBUPDATE macro
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/imaglist.h>
|
||||
|
||||
#if wxUSE_CHECKEDLISTCTRL
|
||||
|
||||
// image indexes (used internally by wxCheckedListCtrl)
|
||||
#define wxCLC_UNCHECKED_IMGIDX 0 // unchecked & enabled
|
||||
#define wxCLC_CHECKED_IMGIDX 1 // checked & enabled
|
||||
#define wxCLC_DISABLED_UNCHECKED_IMGIDX 2 // unchecked & disabled
|
||||
#define wxCLC_DISABLED_CHECKED_IMGIDX 3 // checked & disabled
|
||||
#define wxCLC_UNCHECKED_IMGIDX 0 // unchecked & enabled
|
||||
#define wxCLC_CHECKED_IMGIDX 1 // checked & enabled
|
||||
#define wxCLC_DISABLED_UNCHECKED_IMGIDX 2 // unchecked & disabled
|
||||
#define wxCLC_DISABLED_CHECKED_IMGIDX 3 // checked & disabled
|
||||
|
||||
// additional state flags (wx's defines should end at 0x0100; see listbase.h)
|
||||
#define wxLIST_STATE_CHECKED 0x010000
|
||||
#define wxLIST_STATE_ENABLED 0x100000
|
||||
#define wxLIST_STATE_CHECKED 0x010000
|
||||
#define wxLIST_STATE_ENABLED 0x100000
|
||||
|
||||
// additional wxCheckedListCtrl style flags
|
||||
// (wx's defines should at 0x8000; see listbase.h)
|
||||
#define wxCLC_CHECK_WHEN_SELECTING 0x10000
|
||||
#define wxCLC_CHECK_WHEN_SELECTING 0x10000
|
||||
|
||||
|
||||
// -------------------------
|
||||
|
@ -63,7 +63,7 @@ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_WEBUPDATE, wxEVT_COMMAND_LIST_ITEM_UNCHE
|
|||
class WXDLLIMPEXP_WEBUPDATE wxCheckedListCtrl : public wxListCtrl
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
// we have to keep a different array to keep track of the additional
|
||||
// states we support....
|
||||
wxArrayInt m_stateList;
|
||||
|
@ -79,25 +79,25 @@ public:
|
|||
: wxListCtrl(), m_imageList(16, 16, TRUE) {}
|
||||
#endif
|
||||
|
||||
wxCheckedListCtrl(wxWindow *parent, wxWindowID id = -1,
|
||||
const wxPoint& pt = wxDefaultPosition,
|
||||
const wxSize& sz = wxDefaultSize,
|
||||
long style = wxCLC_CHECK_WHEN_SELECTING,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxListCtrlNameStr)
|
||||
wxCheckedListCtrl(wxWindow* parent, wxWindowID id = -1,
|
||||
const wxPoint &pt = wxDefaultPosition,
|
||||
const wxSize &sz = wxDefaultSize,
|
||||
long style = wxCLC_CHECK_WHEN_SELECTING,
|
||||
const wxValidator &validator = wxDefaultValidator,
|
||||
const wxString &name = wxListCtrlNameStr)
|
||||
#if CLC_VBAM_USAGE && CLC_USE_SYSICONS
|
||||
: wxListCtrl(), m_imageList()
|
||||
: wxListCtrl(), m_imageList()
|
||||
#else
|
||||
: wxListCtrl(), m_imageList(16, 16, TRUE)
|
||||
: wxListCtrl(), m_imageList(16, 16, TRUE)
|
||||
#endif
|
||||
{ Create(parent, id, pt, sz, style, validator, name); }
|
||||
|
||||
bool Create(wxWindow *parent, wxWindowID id = -1,
|
||||
const wxPoint& pt = wxDefaultPosition,
|
||||
const wxSize& sz = wxDefaultSize,
|
||||
long style = wxCLC_CHECK_WHEN_SELECTING,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxListCtrlNameStr);
|
||||
{ Create(parent, id, pt, sz, style, validator, name); }
|
||||
|
||||
bool Create(wxWindow* parent, wxWindowID id = -1,
|
||||
const wxPoint &pt = wxDefaultPosition,
|
||||
const wxSize &sz = wxDefaultSize,
|
||||
long style = wxCLC_CHECK_WHEN_SELECTING,
|
||||
const wxValidator &validator = wxDefaultValidator,
|
||||
const wxString &name = wxListCtrlNameStr);
|
||||
|
||||
#ifdef CLC_VBAM_USAGE
|
||||
// for xrc usage, a separate init function is needed.
|
||||
|
@ -106,19 +106,19 @@ public:
|
|||
virtual ~wxCheckedListCtrl() {}
|
||||
|
||||
|
||||
public: // utilities
|
||||
public: // utilities
|
||||
|
||||
// core overloads (i.e. the most generic overloads)
|
||||
bool GetItem(wxListItem& info) const;
|
||||
bool SetItem(wxListItem& info);
|
||||
long InsertItem(wxListItem& info);
|
||||
bool DeleteItem(long item);
|
||||
bool GetItem(wxListItem &info) const;
|
||||
bool SetItem(wxListItem &info);
|
||||
long InsertItem(wxListItem &info);
|
||||
bool DeleteItem(long item);
|
||||
bool DeleteAllItems()
|
||||
{ m_stateList.Clear(); return wxListCtrl::DeleteAllItems(); }
|
||||
{ m_stateList.Clear(); return wxListCtrl::DeleteAllItems(); }
|
||||
|
||||
bool SortItems(wxListCtrlCompare, long)
|
||||
{ wxASSERT_MSG(0, wxT("Not implemented yet ! sorry... ")); return FALSE; }
|
||||
|
||||
{ wxASSERT_MSG(0, wxT("Not implemented yet ! sorry... ")); return FALSE; }
|
||||
|
||||
// shortcuts to the SetItemState function
|
||||
void Check(long item, bool checked);
|
||||
void Enable(long item, bool enable);
|
||||
|
@ -129,17 +129,17 @@ public: // utilities
|
|||
// However you should use #EnableAll instead of this function if you want to get
|
||||
// good graphics (try to understand)
|
||||
virtual bool Enable(bool enable = true)
|
||||
{ return wxListCtrl::Enable(enable); }
|
||||
{ return wxListCtrl::Enable(enable); }
|
||||
|
||||
// shortcuts to the GetItemState function
|
||||
bool IsChecked(long item) const
|
||||
{ return GetItemState(item, wxLIST_STATE_CHECKED) != 0; }
|
||||
{ return GetItemState(item, wxLIST_STATE_CHECKED) != 0; }
|
||||
bool IsEnabled(long item) const
|
||||
{ return GetItemState(item, wxLIST_STATE_ENABLED) != 0; }
|
||||
{ return GetItemState(item, wxLIST_STATE_ENABLED) != 0; }
|
||||
|
||||
// this needs to be redeclared otherwise it's hidden by our other IsEnabled() function.
|
||||
bool IsEnabled() const
|
||||
{ return wxWindow::IsEnabled(); }
|
||||
{ return wxWindow::IsEnabled(); }
|
||||
|
||||
//! Returns the number of checked items in the control.
|
||||
int GetCheckedItemCount() const;
|
||||
|
@ -148,22 +148,22 @@ public: // utilities
|
|||
// #GetItem and #SetItem functions...
|
||||
bool SetItemState(long item, long state, long stateMask);
|
||||
int GetItemState(long item, long stateMask) const;
|
||||
long InsertItem( long index, const wxString& label, int imageIndex = -1);
|
||||
long SetItem(long index, int col, const wxString& label, int imageId = -1);
|
||||
long InsertItem(long index, const wxString &label, int imageIndex = -1);
|
||||
long SetItem(long index, int col, const wxString &label, int imageId = -1);
|
||||
|
||||
// the image associated with an element is already in used by wxCheckedListCtrl
|
||||
// itself to show the checkbox and it cannot be handled by the user !
|
||||
bool SetItemImage(long, int)
|
||||
{ wxASSERT_MSG(0, wxT("This function cannot be used with wxCheckedListCtrl !")); return FALSE; }
|
||||
{ wxASSERT_MSG(0, wxT("This function cannot be used with wxCheckedListCtrl !")); return FALSE; }
|
||||
|
||||
protected: // event handlers
|
||||
protected: // event handlers
|
||||
|
||||
void OnMouseEvent(wxMouseEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent &event);
|
||||
|
||||
protected: // internal utilities
|
||||
protected: // internal utilities
|
||||
|
||||
static int GetItemImageFromAdditionalState(int addstate);
|
||||
static int GetAndRemoveAdditionalState(long *state, int statemask);
|
||||
static int GetAndRemoveAdditionalState(long* state, int statemask);
|
||||
wxColour GetBgColourFromAdditionalState(int additionalstate);
|
||||
|
||||
private:
|
||||
|
@ -176,7 +176,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#endif // wxUSE_CHECKEDLISTCTRL
|
||||
#endif // wxUSE_CHECKEDLISTCTRL
|
||||
|
||||
#endif // _WX_CHECKEDLISTCTRL_H_
|
||||
#endif // _WX_CHECKEDLISTCTRL_H_
|
||||
|
||||
|
|
|
@ -8,68 +8,70 @@
|
|||
#include "wx/keyedit.h"
|
||||
#include "wx/sdljoy.h"
|
||||
|
||||
typedef struct wxJoyKeyBinding {
|
||||
int key; // key code; listed first for easy static init
|
||||
int mod; // modifier flags
|
||||
int joy; // joystick # (starting at 1)
|
||||
// if joy is non-0, key = control number, and mod = control type
|
||||
typedef struct wxJoyKeyBinding
|
||||
{
|
||||
int key; // key code; listed first for easy static init
|
||||
int mod; // modifier flags
|
||||
int joy; // joystick # (starting at 1)
|
||||
// if joy is non-0, key = control number, and mod = control type
|
||||
} wxJoyKeyBinding;
|
||||
|
||||
typedef std::vector<wxJoyKeyBinding> wxJoyKeyBinding_v;
|
||||
|
||||
// joystick control types
|
||||
// mod for joysticks
|
||||
enum {
|
||||
WXJB_AXIS_PLUS, WXJB_AXIS_MINUS, WXJB_BUTTON, WXJB_HAT_FIRST,
|
||||
WXJB_HAT_N = WXJB_HAT_FIRST, WXJB_HAT_S, WXJB_HAT_W, WXJB_HAT_E, WXJB_HAT_NW,
|
||||
WXJB_HAT_NE, WXJB_HAT_SW, WXJB_HAT_SE, WXJB_HAT_LAST = WXJB_HAT_SE
|
||||
enum
|
||||
{
|
||||
WXJB_AXIS_PLUS, WXJB_AXIS_MINUS, WXJB_BUTTON, WXJB_HAT_FIRST,
|
||||
WXJB_HAT_N = WXJB_HAT_FIRST, WXJB_HAT_S, WXJB_HAT_W, WXJB_HAT_E, WXJB_HAT_NW,
|
||||
WXJB_HAT_NE, WXJB_HAT_SW, WXJB_HAT_SE, WXJB_HAT_LAST = WXJB_HAT_SE
|
||||
};
|
||||
|
||||
class wxJoyKeyTextCtrl : public wxKeyTextCtrl
|
||||
{
|
||||
public:
|
||||
// default constructor; required for use with xrc
|
||||
// FIXME: clearable and keyenter should be style flags
|
||||
wxJoyKeyTextCtrl() : wxKeyTextCtrl() {}
|
||||
virtual ~wxJoyKeyTextCtrl() {};
|
||||
// default constructor; required for use with xrc
|
||||
// FIXME: clearable and keyenter should be style flags
|
||||
wxJoyKeyTextCtrl() : wxKeyTextCtrl() {}
|
||||
virtual ~wxJoyKeyTextCtrl() {};
|
||||
|
||||
// key is event.GetControlIndex(), and joy is event.GetJoy() + 1
|
||||
// mod is derived from GetControlValue() and GetControlType():
|
||||
// convert wxSDLJoyEvent's type+val into mod (WXJB_*)
|
||||
static int DigitalButton(wxSDLJoyEvent &event);
|
||||
// convert mod+key to accel string, separated by -
|
||||
static wxString ToString(int mod, int key, int joy);
|
||||
// convert multiple keys, separated by multikey
|
||||
static wxString ToString(wxJoyKeyBinding_v keys, wxChar sep = wxT(','));
|
||||
// parses single key string into mod+key
|
||||
static bool FromString(const wxString &s, int &mod, int &key, int &joy);
|
||||
// parse multi-key string into array
|
||||
// returns empty array on parse errors
|
||||
static wxJoyKeyBinding_v FromString(const wxString &s, wxChar sep = wxT(','));
|
||||
// parse a single key in given wxChar array up to given len
|
||||
static bool ParseString(const wxChar *s, int len, int &mod, int &key, int &joy);
|
||||
// key is event.GetControlIndex(), and joy is event.GetJoy() + 1
|
||||
// mod is derived from GetControlValue() and GetControlType():
|
||||
// convert wxSDLJoyEvent's type+val into mod (WXJB_*)
|
||||
static int DigitalButton(wxSDLJoyEvent &event);
|
||||
// convert mod+key to accel string, separated by -
|
||||
static wxString ToString(int mod, int key, int joy);
|
||||
// convert multiple keys, separated by multikey
|
||||
static wxString ToString(wxJoyKeyBinding_v keys, wxChar sep = wxT(','));
|
||||
// parses single key string into mod+key
|
||||
static bool FromString(const wxString &s, int &mod, int &key, int &joy);
|
||||
// parse multi-key string into array
|
||||
// returns empty array on parse errors
|
||||
static wxJoyKeyBinding_v FromString(const wxString &s, wxChar sep = wxT(','));
|
||||
// parse a single key in given wxChar array up to given len
|
||||
static bool ParseString(const wxChar* s, int len, int &mod, int &key, int &joy);
|
||||
|
||||
protected:
|
||||
void OnJoy(wxSDLJoyEvent &);
|
||||
void OnJoy(wxSDLJoyEvent &);
|
||||
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
DECLARE_EVENT_TABLE();
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
// A simple copy-only validator
|
||||
class wxJoyKeyValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxJoyKeyValidator(wxJoyKeyBinding_v *v) : wxValidator(), val(v) {}
|
||||
wxJoyKeyValidator(const wxJoyKeyValidator &v) : wxValidator(), val(v.val) {}
|
||||
wxObject *Clone() const { return new wxJoyKeyValidator(val); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxJoyKeyValidator(wxJoyKeyBinding_v* v) : wxValidator(), val(v) {}
|
||||
wxJoyKeyValidator(const wxJoyKeyValidator &v) : wxValidator(), val(v.val) {}
|
||||
wxObject* Clone() const { return new wxJoyKeyValidator(val); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
wxJoyKeyBinding_v *val;
|
||||
wxJoyKeyBinding_v* val;
|
||||
|
||||
DECLARE_CLASS(wxJoyKeyValidator)
|
||||
DECLARE_CLASS(wxJoyKeyValidator)
|
||||
};
|
||||
|
||||
#endif /* WX_JOYKEYTEXT_H */
|
||||
|
|
|
@ -14,62 +14,62 @@ typedef std::vector<wxAcceleratorEntry> wxAcceleratorEntry_v;
|
|||
class wxKeyTextCtrl : public wxTextCtrl
|
||||
{
|
||||
public:
|
||||
// default constructor; required for use with xrc
|
||||
// FIXME: clearable and keyenter should be style flags
|
||||
wxKeyTextCtrl() : wxTextCtrl(), clearable(true), multikey(wxT(',')),
|
||||
keyenter(true), lastmod(0), lastkey(0) {};
|
||||
virtual ~wxKeyTextCtrl() {};
|
||||
// default constructor; required for use with xrc
|
||||
// FIXME: clearable and keyenter should be style flags
|
||||
wxKeyTextCtrl() : wxTextCtrl(), clearable(true), multikey(wxT(',')),
|
||||
keyenter(true), lastmod(0), lastkey(0) {};
|
||||
virtual ~wxKeyTextCtrl() {};
|
||||
|
||||
void SetClearable(bool set = true) { clearable = set; }
|
||||
void SetMultikey(wxChar c = wxT(',')) { multikey = c; }
|
||||
void SetKeyEnter(bool set = true) { keyenter = set; }
|
||||
void SetClearable(bool set = true) { clearable = set; }
|
||||
void SetMultikey(wxChar c = wxT(',')) { multikey = c; }
|
||||
void SetKeyEnter(bool set = true) { keyenter = set; }
|
||||
|
||||
bool GetClearable() { return clearable; }
|
||||
wxChar GetMultikey() { return multikey; }
|
||||
bool GetKeyEnter() { return keyenter; }
|
||||
bool GetClearable() { return clearable; }
|
||||
wxChar GetMultikey() { return multikey; }
|
||||
bool GetKeyEnter() { return keyenter; }
|
||||
|
||||
// convert mod+key to accel string, separated by -
|
||||
static wxString ToString(int mod, int key);
|
||||
// convert multiple keys, separated by multikey
|
||||
static wxString ToString(wxAcceleratorEntry_v keys, wxChar sep = wxT(','));
|
||||
// parses single key string into mod+key
|
||||
static bool FromString(const wxString &s, int &mod, int &key);
|
||||
// parse multi-key string into accelentry array
|
||||
// note that meta flag may be set in accelentry array item even
|
||||
// where not supported for accelerators (i.e. non-mac)
|
||||
// returns empty array on parse errors
|
||||
static wxAcceleratorEntry_v FromString(const wxString &s, wxChar sep = wxT(','));
|
||||
// parse a single key in given wxChar array up to given len
|
||||
static bool ParseString(const wxChar *s, int len, int &mod, int &key);
|
||||
// convert mod+key to accel string, separated by -
|
||||
static wxString ToString(int mod, int key);
|
||||
// convert multiple keys, separated by multikey
|
||||
static wxString ToString(wxAcceleratorEntry_v keys, wxChar sep = wxT(','));
|
||||
// parses single key string into mod+key
|
||||
static bool FromString(const wxString &s, int &mod, int &key);
|
||||
// parse multi-key string into accelentry array
|
||||
// note that meta flag may be set in accelentry array item even
|
||||
// where not supported for accelerators (i.e. non-mac)
|
||||
// returns empty array on parse errors
|
||||
static wxAcceleratorEntry_v FromString(const wxString &s, wxChar sep = wxT(','));
|
||||
// parse a single key in given wxChar array up to given len
|
||||
static bool ParseString(const wxChar* s, int len, int &mod, int &key);
|
||||
|
||||
protected:
|
||||
void OnKeyDown(wxKeyEvent &);
|
||||
void OnKeyUp(wxKeyEvent &);
|
||||
void OnKeyDown(wxKeyEvent &);
|
||||
void OnKeyUp(wxKeyEvent &);
|
||||
|
||||
bool clearable;
|
||||
wxChar multikey;
|
||||
bool keyenter;
|
||||
// the last keydown event received; this is processed on next keyup
|
||||
int lastmod, lastkey;
|
||||
bool clearable;
|
||||
wxChar multikey;
|
||||
bool keyenter;
|
||||
// the last keydown event received; this is processed on next keyup
|
||||
int lastmod, lastkey;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
DECLARE_EVENT_TABLE();
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
// A simple copy-only validator
|
||||
class wxKeyValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxKeyValidator(wxAcceleratorEntry_v *v) : wxValidator(), val(v) {}
|
||||
wxKeyValidator(const wxKeyValidator &v) : wxValidator(), val(v.val) {}
|
||||
wxObject *Clone() const { return new wxKeyValidator(val); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxKeyValidator(wxAcceleratorEntry_v* v) : wxValidator(), val(v) {}
|
||||
wxKeyValidator(const wxKeyValidator &v) : wxValidator(), val(v.val) {}
|
||||
wxObject* Clone() const { return new wxKeyValidator(val); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
wxAcceleratorEntry_v *val;
|
||||
wxAcceleratorEntry_v* val;
|
||||
|
||||
DECLARE_CLASS(wxKeyValidator)
|
||||
DECLARE_CLASS(wxKeyValidator)
|
||||
};
|
||||
|
||||
#endif /* WX_KEYTEXT_H */
|
||||
|
|
|
@ -18,77 +18,78 @@ typedef struct wxSDLJoyState wxSDLJoyState_t;
|
|||
class wxSDLJoy : public wxTimer
|
||||
{
|
||||
public:
|
||||
// if analog, send events for all axis movement
|
||||
// otherwise, only send events when values cross the 50% mark
|
||||
// and max out values
|
||||
wxSDLJoy(bool analog = false);
|
||||
// but flag can be set later
|
||||
void SetAnalog(bool analog = true) { digital = !analog; };
|
||||
// send events to this handler
|
||||
// If NULL (default), send to window with keyboard focus
|
||||
wxEvtHandler *Attach(wxEvtHandler *);
|
||||
// add another joystick to the list of polled sticks
|
||||
// -1 == add all
|
||||
// If joy > # of joysticks, it is ignored
|
||||
// This will start polling if a valid joystick is selected
|
||||
void Add(int joy = -1);
|
||||
// remove a joystick from the polled sticks
|
||||
// -1 == remove all
|
||||
// If joy > # of joysticks, it is ignored
|
||||
// This will stop polling if all joysticks are disabled
|
||||
void Remove(int joy = -1);
|
||||
// query if a stick is being polled
|
||||
bool IsPolling(int joy);
|
||||
// query # of joysticks
|
||||
int GetNumJoysticks() { return njoy; }
|
||||
// query # of axes on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumAxes(int joy);
|
||||
// query # of hats on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumHats(int joy);
|
||||
// query # of buttons on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumButtons(int joy);
|
||||
// if analog, send events for all axis movement
|
||||
// otherwise, only send events when values cross the 50% mark
|
||||
// and max out values
|
||||
wxSDLJoy(bool analog = false);
|
||||
// but flag can be set later
|
||||
void SetAnalog(bool analog = true) { digital = !analog; };
|
||||
// send events to this handler
|
||||
// If NULL (default), send to window with keyboard focus
|
||||
wxEvtHandler* Attach(wxEvtHandler*);
|
||||
// add another joystick to the list of polled sticks
|
||||
// -1 == add all
|
||||
// If joy > # of joysticks, it is ignored
|
||||
// This will start polling if a valid joystick is selected
|
||||
void Add(int joy = -1);
|
||||
// remove a joystick from the polled sticks
|
||||
// -1 == remove all
|
||||
// If joy > # of joysticks, it is ignored
|
||||
// This will stop polling if all joysticks are disabled
|
||||
void Remove(int joy = -1);
|
||||
// query if a stick is being polled
|
||||
bool IsPolling(int joy);
|
||||
// query # of joysticks
|
||||
int GetNumJoysticks() { return njoy; }
|
||||
// query # of axes on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumAxes(int joy);
|
||||
// query # of hats on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumHats(int joy);
|
||||
// query # of buttons on given joystick
|
||||
// 0 is returned if joy is invalid
|
||||
int GetNumButtons(int joy);
|
||||
|
||||
virtual ~wxSDLJoy();
|
||||
virtual ~wxSDLJoy();
|
||||
protected:
|
||||
bool digital;
|
||||
int njoy;
|
||||
wxSDLJoyState_t *joystate;
|
||||
wxEvtHandler *evthandler;
|
||||
bool nosticks;
|
||||
void Notify();
|
||||
bool digital;
|
||||
int njoy;
|
||||
wxSDLJoyState_t* joystate;
|
||||
wxEvtHandler* evthandler;
|
||||
bool nosticks;
|
||||
void Notify();
|
||||
};
|
||||
|
||||
enum {
|
||||
// The types of supported controls
|
||||
// values are signed-16 for axis, 0/1 for button
|
||||
// hat is bitmask NESW/URDL
|
||||
WXSDLJOY_AXIS, WXSDLJOY_HAT, WXSDLJOY_BUTTON
|
||||
enum
|
||||
{
|
||||
// The types of supported controls
|
||||
// values are signed-16 for axis, 0/1 for button
|
||||
// hat is bitmask NESW/URDL
|
||||
WXSDLJOY_AXIS, WXSDLJOY_HAT, WXSDLJOY_BUTTON
|
||||
};
|
||||
|
||||
class wxSDLJoyEvent : public wxCommandEvent
|
||||
{
|
||||
friend class wxSDLJoy;
|
||||
friend class wxSDLJoy;
|
||||
public:
|
||||
// Default constructor
|
||||
wxSDLJoyEvent(wxEventType commandType = wxEVT_NULL, int id = 0) :
|
||||
wxCommandEvent(commandType, id) {}
|
||||
// accessors
|
||||
unsigned short GetJoy() { return joy; }
|
||||
unsigned short GetControlType() { return ctrl_type; }
|
||||
unsigned short GetControlIndex() { return ctrl_idx; }
|
||||
short GetControlValue() { return ctrl_val; }
|
||||
short GetControlPrevValue() { return prev_val; }
|
||||
// required for PostEvent, apparently
|
||||
wxEvent *Clone();
|
||||
// Default constructor
|
||||
wxSDLJoyEvent(wxEventType commandType = wxEVT_NULL, int id = 0) :
|
||||
wxCommandEvent(commandType, id) {}
|
||||
// accessors
|
||||
unsigned short GetJoy() { return joy; }
|
||||
unsigned short GetControlType() { return ctrl_type; }
|
||||
unsigned short GetControlIndex() { return ctrl_idx; }
|
||||
short GetControlValue() { return ctrl_val; }
|
||||
short GetControlPrevValue() { return prev_val; }
|
||||
// required for PostEvent, apparently
|
||||
wxEvent* Clone();
|
||||
protected:
|
||||
unsigned short joy;
|
||||
unsigned short ctrl_type;
|
||||
unsigned short ctrl_idx;
|
||||
short ctrl_val;
|
||||
short prev_val;
|
||||
unsigned short joy;
|
||||
unsigned short ctrl_type;
|
||||
unsigned short ctrl_idx;
|
||||
short ctrl_val;
|
||||
short prev_val;
|
||||
};
|
||||
|
||||
// Note: this means sdljoy can't be part of a library w/o extra work
|
||||
|
@ -96,7 +97,7 @@ DECLARE_LOCAL_EVENT_TYPE(wxEVT_SDLJOY, -1)
|
|||
typedef void (wxEvtHandler::*wxSDLJoyEventFunction)(wxSDLJoyEvent &);
|
||||
#define EVT_SDLJOY(fn) \
|
||||
DECLARE_EVENT_TABLE_ENTRY(wxEVT_SDLJOY, wxID_ANY, wxID_ANY, \
|
||||
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction) \
|
||||
wxStaticCastEvent(wxSDLJoyEventFunction, &fn), (wxObject *)NULL), \
|
||||
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction) \
|
||||
wxStaticCastEvent(wxSDLJoyEventFunction, &fn), (wxObject *)NULL), \
|
||||
|
||||
#endif /* JOYEVT_H */
|
||||
|
|
|
@ -7,21 +7,21 @@
|
|||
class wxFarRadio : public wxCheckBox
|
||||
{
|
||||
public:
|
||||
wxFarRadio();
|
||||
virtual ~wxFarRadio();
|
||||
void SetValue(bool val);
|
||||
// join this group with widget(s) in grp
|
||||
void SetGroup(class wxFarRadio *grp);
|
||||
// turn into a singleton
|
||||
void BreakGroup();
|
||||
// iterate over members in group (ring)
|
||||
wxFarRadio *GetNext();
|
||||
wxFarRadio();
|
||||
virtual ~wxFarRadio();
|
||||
void SetValue(bool val);
|
||||
// join this group with widget(s) in grp
|
||||
void SetGroup(class wxFarRadio* grp);
|
||||
// turn into a singleton
|
||||
void BreakGroup();
|
||||
// iterate over members in group (ring)
|
||||
wxFarRadio* GetNext();
|
||||
protected:
|
||||
void UpdatedValue();
|
||||
void UpdateEvt(wxCommandEvent &ev);
|
||||
wxFarRadio *Next;
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
void UpdatedValue();
|
||||
void UpdateEvt(wxCommandEvent &ev);
|
||||
wxFarRadio* Next;
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
// boolean copy-only validator that uses a constant int
|
||||
|
@ -29,16 +29,16 @@ protected:
|
|||
class wxBoolIntValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxBoolIntValidator(int *_vptr, int _val, int _mask = ~0) : wxValidator(),
|
||||
vptr(_vptr), val(_val), mask(_mask) {}
|
||||
wxBoolIntValidator(const wxBoolIntValidator &v) : wxValidator(),
|
||||
vptr(v.vptr), val(v.val), mask(v.mask) {}
|
||||
wxObject *Clone() const { return new wxBoolIntValidator(vptr, val, mask); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxBoolIntValidator(int* _vptr, int _val, int _mask = ~0) : wxValidator(),
|
||||
vptr(_vptr), val(_val), mask(_mask) {}
|
||||
wxBoolIntValidator(const wxBoolIntValidator &v) : wxValidator(),
|
||||
vptr(v.vptr), val(v.val), mask(v.mask) {}
|
||||
wxObject* Clone() const { return new wxBoolIntValidator(vptr, val, mask); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
int val, mask, *vptr;
|
||||
int val, mask, *vptr;
|
||||
};
|
||||
|
||||
// boolean copy-only validator with reversed value
|
||||
|
@ -46,29 +46,29 @@ protected:
|
|||
class wxBoolRevValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxBoolRevValidator(bool *_vptr) : wxValidator(), vptr(_vptr) {}
|
||||
wxBoolRevValidator(const wxBoolRevValidator &v) : wxValidator(), vptr(v.vptr) {}
|
||||
wxObject *Clone() const { return new wxBoolRevValidator(vptr); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxBoolRevValidator(bool* _vptr) : wxValidator(), vptr(_vptr) {}
|
||||
wxBoolRevValidator(const wxBoolRevValidator &v) : wxValidator(), vptr(v.vptr) {}
|
||||
wxObject* Clone() const { return new wxBoolRevValidator(vptr); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
bool *vptr;
|
||||
bool* vptr;
|
||||
};
|
||||
|
||||
// wxFilePickerCtrl/wxDirPickerCtrl copy-only vvalidator
|
||||
class wxFileDirPickerValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxFileDirPickerValidator(wxString *_vptr) : wxValidator(), vptr(_vptr) {}
|
||||
wxFileDirPickerValidator(const wxFileDirPickerValidator &v) : wxValidator(),
|
||||
vptr(v.vptr) {}
|
||||
wxObject *Clone() const { return new wxFileDirPickerValidator(vptr); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxFileDirPickerValidator(wxString* _vptr) : wxValidator(), vptr(_vptr) {}
|
||||
wxFileDirPickerValidator(const wxFileDirPickerValidator &v) : wxValidator(),
|
||||
vptr(v.vptr) {}
|
||||
wxObject* Clone() const { return new wxFileDirPickerValidator(vptr); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
wxString *vptr;
|
||||
wxString* vptr;
|
||||
};
|
||||
|
||||
|
||||
|
@ -81,17 +81,17 @@ protected:
|
|||
class wxColorValidator : public wxValidator
|
||||
{
|
||||
public:
|
||||
wxColorValidator(uint32_t *vptr) : wxValidator(), ptr32(vptr), ptr16(0) {}
|
||||
wxColorValidator(uint16_t *vptr) : wxValidator(), ptr16(vptr), ptr32(0) {}
|
||||
wxColorValidator(const wxColorValidator &v) : wxValidator(),
|
||||
ptr32(v.ptr32), ptr16(v.ptr16) {}
|
||||
wxObject *Clone() const { return new wxColorValidator(*this); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow *p) { return true; }
|
||||
wxColorValidator(uint32_t* vptr) : wxValidator(), ptr32(vptr), ptr16(0) {}
|
||||
wxColorValidator(uint16_t* vptr) : wxValidator(), ptr16(vptr), ptr32(0) {}
|
||||
wxColorValidator(const wxColorValidator &v) : wxValidator(),
|
||||
ptr32(v.ptr32), ptr16(v.ptr16) {}
|
||||
wxObject* Clone() const { return new wxColorValidator(*this); }
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p) { return true; }
|
||||
protected:
|
||||
uint32_t *ptr32;
|
||||
uint16_t *ptr16;
|
||||
uint32_t* ptr32;
|
||||
uint16_t* ptr16;
|
||||
};
|
||||
|
||||
// Copy-only validators for checkboxes and radio buttons that enables a set
|
||||
|
@ -103,62 +103,62 @@ protected:
|
|||
|
||||
// there's probably a standard wxWindowList or some such, but it's
|
||||
// undocumented and I prefer arrays
|
||||
typedef std::vector<wxWindow *>wxWindow_v;
|
||||
typedef std::vector<wxWindow*>wxWindow_v;
|
||||
|
||||
class wxBoolEnValidator : public wxGenericValidator
|
||||
{
|
||||
public:
|
||||
wxBoolEnValidator(bool *vptr) : wxGenericValidator(vptr) {}
|
||||
wxBoolEnValidator(bool *vptr, wxWindow_v &cnt, std::vector<int>rev = std::vector<int>()) :
|
||||
wxGenericValidator(vptr), controls(cnt), reverse(rev) {}
|
||||
wxBoolEnValidator(const wxBoolEnValidator &v) : wxGenericValidator(v),
|
||||
controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject *Clone() const { return new wxBoolEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
wxBoolEnValidator(bool* vptr) : wxGenericValidator(vptr) {}
|
||||
wxBoolEnValidator(bool* vptr, wxWindow_v &cnt, std::vector<int>rev = std::vector<int>()) :
|
||||
wxGenericValidator(vptr), controls(cnt), reverse(rev) {}
|
||||
wxBoolEnValidator(const wxBoolEnValidator &v) : wxGenericValidator(v),
|
||||
controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject* Clone() const { return new wxBoolEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
class wxBoolIntEnValidator : public wxBoolIntValidator
|
||||
{
|
||||
public:
|
||||
wxBoolIntEnValidator(int *vptr, int val, int mask = ~0) :
|
||||
wxBoolIntValidator(vptr, val, mask) {}
|
||||
wxBoolIntEnValidator(int *vptr, int val, int mask, wxWindow_v &cnt,
|
||||
std::vector<int>rev = std::vector<int>()) :
|
||||
wxBoolIntValidator(vptr, val, mask), controls(cnt), reverse(rev) {}
|
||||
wxBoolIntEnValidator(const wxBoolIntEnValidator &v) :
|
||||
wxBoolIntValidator(v), controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject *Clone() const { return new wxBoolIntEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
wxBoolIntEnValidator(int* vptr, int val, int mask = ~0) :
|
||||
wxBoolIntValidator(vptr, val, mask) {}
|
||||
wxBoolIntEnValidator(int* vptr, int val, int mask, wxWindow_v &cnt,
|
||||
std::vector<int>rev = std::vector<int>()) :
|
||||
wxBoolIntValidator(vptr, val, mask), controls(cnt), reverse(rev) {}
|
||||
wxBoolIntEnValidator(const wxBoolIntEnValidator &v) :
|
||||
wxBoolIntValidator(v), controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject* Clone() const { return new wxBoolIntEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
class wxBoolRevEnValidator : public wxBoolRevValidator
|
||||
{
|
||||
public:
|
||||
wxBoolRevEnValidator(bool *vptr) : wxBoolRevValidator(vptr) {}
|
||||
wxBoolRevEnValidator(bool *vptr, wxWindow_v &cnt, std::vector<int>rev = std::vector<int>()) :
|
||||
wxBoolRevValidator(vptr), controls(cnt), reverse(rev) {}
|
||||
wxBoolRevEnValidator(const wxBoolRevEnValidator &v) : wxBoolRevValidator(v),
|
||||
controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject *Clone() const { return new wxBoolRevEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
wxBoolRevEnValidator(bool* vptr) : wxBoolRevValidator(vptr) {}
|
||||
wxBoolRevEnValidator(bool* vptr, wxWindow_v &cnt, std::vector<int>rev = std::vector<int>()) :
|
||||
wxBoolRevValidator(vptr), controls(cnt), reverse(rev) {}
|
||||
wxBoolRevEnValidator(const wxBoolRevEnValidator &v) : wxBoolRevValidator(v),
|
||||
controls(v.controls), reverse(v.reverse) {}
|
||||
wxObject* Clone() const { return new wxBoolRevEnValidator(*this); }
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
// and here's an event handler that can be attached to the widget or a parent
|
||||
|
@ -168,23 +168,23 @@ public:
|
|||
class wxBoolEnHandler : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
wxWindow_v controls;
|
||||
std::vector<int> reverse;
|
||||
void ToggleCheck(wxCommandEvent &ev);
|
||||
void Enable(wxCommandEvent &ev);
|
||||
void Disable(wxCommandEvent &ev);
|
||||
wxWindow_v controls;
|
||||
std::vector<int> reverse;
|
||||
void ToggleCheck(wxCommandEvent &ev);
|
||||
void Enable(wxCommandEvent &ev);
|
||||
void Disable(wxCommandEvent &ev);
|
||||
};
|
||||
|
||||
// use this to connect to the handler of id in win to obj
|
||||
#define wxCBBoolEnHandlerConnect(win, id, obj) \
|
||||
(win)->Connect(id, wxEVT_COMMAND_CHECKBOX_CLICKED, \
|
||||
wxCommandEventHandler(wxBoolEnHandler::ToggleCheck), NULL, \
|
||||
&obj)
|
||||
wxCommandEventHandler(wxBoolEnHandler::ToggleCheck), NULL, \
|
||||
&obj)
|
||||
|
||||
#define wxRBBoolEnHandlerConnect(win, id, obj, f) \
|
||||
(win)->Connect(id, wxEVT_COMMAND_RADIOBUTTON_SELECTED, \
|
||||
wxCommandEventHandler(wxBoolEnHandler::f), NULL, \
|
||||
&obj)
|
||||
wxCommandEventHandler(wxBoolEnHandler::f), NULL, \
|
||||
&obj)
|
||||
|
||||
#define wxRBEBoolEnHandlerConnect(win, id, obj) wxRBBoolEnHandlerConnect(win, id, obj, Enable)
|
||||
#define wxRBDBoolEnHandlerConnect(win, id, obj) wxRBBoolEnHandlerConnect(win, id, obj, Disable)
|
||||
|
|
|
@ -3,254 +3,322 @@
|
|||
#include "wx/wxmisc.h"
|
||||
|
||||
wxFarRadio::wxFarRadio()
|
||||
: wxCheckBox()
|
||||
: wxCheckBox()
|
||||
{
|
||||
Next = this;
|
||||
Next = this;
|
||||
}
|
||||
|
||||
wxFarRadio::~wxFarRadio()
|
||||
{
|
||||
BreakGroup();
|
||||
BreakGroup();
|
||||
}
|
||||
|
||||
void wxFarRadio::SetValue(bool val)
|
||||
{
|
||||
wxCheckBox::SetValue(val);
|
||||
UpdatedValue();
|
||||
wxCheckBox::SetValue(val);
|
||||
UpdatedValue();
|
||||
}
|
||||
|
||||
void wxFarRadio::SetGroup(class wxFarRadio *grp)
|
||||
void wxFarRadio::SetGroup(class wxFarRadio* grp)
|
||||
{
|
||||
if(grp == this)
|
||||
return;
|
||||
wxFarRadio *checked = GetValue() ? this : NULL;
|
||||
for(wxFarRadio *gp = Next; gp != this; gp = gp->Next) {
|
||||
if(gp = grp)
|
||||
return;
|
||||
if(gp->GetValue())
|
||||
checked = gp;
|
||||
}
|
||||
wxFarRadio *link = Next;
|
||||
Next = grp;
|
||||
bool clear_checked = false;
|
||||
wxFarRadio *gp;
|
||||
for(gp = grp; gp->Next != grp; gp = gp->Next) {
|
||||
if(checked && GetValue())
|
||||
clear_checked = true;
|
||||
}
|
||||
gp->Next = link;
|
||||
if(checked && gp->GetValue())
|
||||
clear_checked = true;
|
||||
if(clear_checked)
|
||||
checked->SetValue(false);
|
||||
int l;
|
||||
for(l = 1, gp = Next; gp != this; gp = gp->Next, l++);
|
||||
if (grp == this)
|
||||
return;
|
||||
|
||||
wxFarRadio* checked = GetValue() ? this : NULL;
|
||||
|
||||
for (wxFarRadio* gp = Next; gp != this; gp = gp->Next)
|
||||
{
|
||||
if (gp = grp)
|
||||
return;
|
||||
|
||||
if (gp->GetValue())
|
||||
checked = gp;
|
||||
}
|
||||
|
||||
wxFarRadio* link = Next;
|
||||
Next = grp;
|
||||
bool clear_checked = false;
|
||||
wxFarRadio* gp;
|
||||
|
||||
for (gp = grp; gp->Next != grp; gp = gp->Next)
|
||||
{
|
||||
if (checked && GetValue())
|
||||
clear_checked = true;
|
||||
}
|
||||
|
||||
gp->Next = link;
|
||||
|
||||
if (checked && gp->GetValue())
|
||||
clear_checked = true;
|
||||
|
||||
if (clear_checked)
|
||||
checked->SetValue(false);
|
||||
|
||||
int l;
|
||||
|
||||
for (l = 1, gp = Next; gp != this; gp = gp->Next, l++);
|
||||
}
|
||||
|
||||
void wxFarRadio::BreakGroup() {
|
||||
wxFarRadio **gp;
|
||||
for(gp = &Next; *gp != this; gp = &(*gp)->Next);
|
||||
*gp = Next;
|
||||
Next = this;
|
||||
}
|
||||
|
||||
wxFarRadio *wxFarRadio::GetNext()
|
||||
void wxFarRadio::BreakGroup()
|
||||
{
|
||||
return Next;
|
||||
wxFarRadio** gp;
|
||||
|
||||
for (gp = &Next; *gp != this; gp = &(*gp)->Next);
|
||||
|
||||
*gp = Next;
|
||||
Next = this;
|
||||
}
|
||||
|
||||
wxFarRadio* wxFarRadio::GetNext()
|
||||
{
|
||||
return Next;
|
||||
}
|
||||
|
||||
void wxFarRadio::UpdatedValue()
|
||||
{
|
||||
if(!GetValue()) {
|
||||
wxFarRadio *gp;
|
||||
// just like system wx, ensure at least one always checked
|
||||
for(gp = Next; gp != this; gp = gp->Next)
|
||||
if(gp->GetValue())
|
||||
break;
|
||||
if(gp == this) {
|
||||
SetValue(true);
|
||||
return;
|
||||
if (!GetValue())
|
||||
{
|
||||
wxFarRadio* gp;
|
||||
|
||||
// just like system wx, ensure at least one always checked
|
||||
for (gp = Next; gp != this; gp = gp->Next)
|
||||
if (gp->GetValue())
|
||||
break;
|
||||
|
||||
if (gp == this)
|
||||
{
|
||||
SetValue(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
for(wxFarRadio *gp = Next; gp != this; gp = gp->Next)
|
||||
gp->SetValue(false);
|
||||
else
|
||||
for (wxFarRadio* gp = Next; gp != this; gp = gp->Next)
|
||||
gp->SetValue(false);
|
||||
}
|
||||
|
||||
void wxFarRadio::UpdateEvt(wxCommandEvent &ev)
|
||||
{
|
||||
UpdatedValue();
|
||||
ev.Skip();
|
||||
UpdatedValue();
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxFarRadio, wxCheckBox);
|
||||
BEGIN_EVENT_TABLE(wxFarRadio, wxCheckBox)
|
||||
EVT_CHECKBOX(wxID_ANY, wxFarRadio::UpdateEvt)
|
||||
EVT_CHECKBOX(wxID_ANY, wxFarRadio::UpdateEvt)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
bool wxBoolIntValidator::TransferToWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
bool checked = (*vptr & mask) == val;
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb)
|
||||
{
|
||||
cb->SetValue(checked);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb)
|
||||
{
|
||||
rb->SetValue(checked);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
bool checked = (*vptr & mask) == val;
|
||||
wxCheckBox *cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
if(cb) {
|
||||
cb->SetValue(checked);
|
||||
return true;
|
||||
}
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
if(rb) {
|
||||
rb->SetValue(checked);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxBoolIntValidator::TransferFromWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
return false;
|
||||
bool nv = false;
|
||||
wxCheckBox *cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
if(cb)
|
||||
nv = cb->GetValue();
|
||||
else {
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
if(rb)
|
||||
nv = rb->GetValue();
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
bool nv = false;
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb)
|
||||
nv = cb->GetValue();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if(mask == ~0 && !nv && *vptr != val)
|
||||
{
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb)
|
||||
nv = rb->GetValue();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mask == ~0 && !nv && *vptr != val)
|
||||
return true;
|
||||
|
||||
*vptr = (*vptr & ~mask) | (nv ? val : 0);
|
||||
return true;
|
||||
*vptr = (*vptr & ~mask) | (nv ? val : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxBoolRevValidator::TransferToWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb)
|
||||
{
|
||||
cb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb)
|
||||
{
|
||||
rb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
wxCheckBox *cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
if(cb) {
|
||||
cb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
if(rb) {
|
||||
rb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxBoolRevValidator::TransferFromWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
return false;
|
||||
wxCheckBox *cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
if(cb)
|
||||
*vptr = !cb->GetValue();
|
||||
else {
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
if(rb)
|
||||
*vptr = !rb->GetValue();
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb)
|
||||
*vptr = !cb->GetValue();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
{
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb)
|
||||
*vptr = !rb->GetValue();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <wx/filepicker.h>
|
||||
|
||||
bool wxFileDirPickerValidator::TransferToWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxFilePickerCtrl* fp = wxDynamicCast(GetWindow(), wxFilePickerCtrl);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fp->SetPath(*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxDirPickerCtrl* dp = wxDynamicCast(GetWindow(), wxDirPickerCtrl);
|
||||
|
||||
if (dp)
|
||||
{
|
||||
dp->SetPath(*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
wxFilePickerCtrl *fp = wxDynamicCast(GetWindow(), wxFilePickerCtrl);
|
||||
if(fp) {
|
||||
fp->SetPath(*vptr);
|
||||
return true;
|
||||
}
|
||||
wxDirPickerCtrl *dp = wxDynamicCast(GetWindow(), wxDirPickerCtrl);
|
||||
if(dp) {
|
||||
dp->SetPath(*vptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxFileDirPickerValidator::TransferFromWindow()
|
||||
{
|
||||
if(!vptr)
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxFilePickerCtrl* fp = wxDynamicCast(GetWindow(), wxFilePickerCtrl);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
*vptr = fp->GetPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
wxDirPickerCtrl* dp = wxDynamicCast(GetWindow(), wxDirPickerCtrl);
|
||||
|
||||
if (dp)
|
||||
{
|
||||
*vptr = dp->GetPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
wxFilePickerCtrl *fp = wxDynamicCast(GetWindow(), wxFilePickerCtrl);
|
||||
if(fp) {
|
||||
*vptr = fp->GetPath();
|
||||
return true;
|
||||
}
|
||||
wxDirPickerCtrl *dp = wxDynamicCast(GetWindow(), wxDirPickerCtrl);
|
||||
if(dp) {
|
||||
*vptr = dp->GetPath();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#include <wx/clrpicker.h>
|
||||
|
||||
bool wxColorValidator::TransferToWindow()
|
||||
{
|
||||
if(!ptr32 && !ptr16)
|
||||
return false;
|
||||
wxColourPickerCtrl *cp = wxDynamicCast(GetWindow(), wxColourPickerCtrl);
|
||||
if(!cp)
|
||||
return false;
|
||||
if(ptr32)
|
||||
cp->SetColour(wxColor(((*ptr32 >> 16) & 0xff),
|
||||
((*ptr32 >> 8) & 0xff),
|
||||
((*ptr32) & 0xff)));
|
||||
else
|
||||
cp->SetColour(wxColor(((*ptr16 << 3) & 0xf8),
|
||||
((*ptr16 >> 2) & 0xf8),
|
||||
((*ptr16 >> 7) & 0xf8)));
|
||||
return true;
|
||||
if (!ptr32 && !ptr16)
|
||||
return false;
|
||||
|
||||
wxColourPickerCtrl* cp = wxDynamicCast(GetWindow(), wxColourPickerCtrl);
|
||||
|
||||
if (!cp)
|
||||
return false;
|
||||
|
||||
if (ptr32)
|
||||
cp->SetColour(wxColor(((*ptr32 >> 16) & 0xff),
|
||||
((*ptr32 >> 8) & 0xff),
|
||||
((*ptr32) & 0xff)));
|
||||
else
|
||||
cp->SetColour(wxColor(((*ptr16 << 3) & 0xf8),
|
||||
((*ptr16 >> 2) & 0xf8),
|
||||
((*ptr16 >> 7) & 0xf8)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxColorValidator::TransferFromWindow()
|
||||
{
|
||||
if(!ptr32 && !ptr16)
|
||||
return false;
|
||||
wxColourPickerCtrl *cp = wxDynamicCast(GetWindow(), wxColourPickerCtrl);
|
||||
if(!cp)
|
||||
return false;
|
||||
wxColor c = cp->GetColour();
|
||||
if(ptr32)
|
||||
*ptr32 = ((c.Red() & 0xff) << 16) +
|
||||
((c.Green() & 0xff) << 8) +
|
||||
((c.Blue() & 0xff));
|
||||
else
|
||||
*ptr16 = ((c.Red() & 0xf8) >> 3) +
|
||||
((c.Green() & 0xf8) << 2) +
|
||||
((c.Blue() & 0xf8) << 7);
|
||||
return true;
|
||||
if (!ptr32 && !ptr16)
|
||||
return false;
|
||||
|
||||
wxColourPickerCtrl* cp = wxDynamicCast(GetWindow(), wxColourPickerCtrl);
|
||||
|
||||
if (!cp)
|
||||
return false;
|
||||
|
||||
wxColor c = cp->GetColour();
|
||||
|
||||
if (ptr32)
|
||||
*ptr32 = ((c.Red() & 0xff) << 16) +
|
||||
((c.Green() & 0xff) << 8) +
|
||||
((c.Blue() & 0xff));
|
||||
else
|
||||
*ptr16 = ((c.Red() & 0xf8) >> 3) +
|
||||
((c.Green() & 0xf8) << 2) +
|
||||
((c.Blue() & 0xf8) << 7);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void enable(wxWindow_v controls, std::vector<int>reverse, bool en)
|
||||
{
|
||||
for(int i = 0; i < controls.size(); i++)
|
||||
controls[i]->Enable(reverse.size() <= i || !reverse[i] ? en : !en);
|
||||
for (int i = 0; i < controls.size(); i++)
|
||||
controls[i]->Enable(reverse.size() <= i || !reverse[i] ? en : !en);
|
||||
}
|
||||
|
||||
#define boolen(r) do { \
|
||||
int en; \
|
||||
wxCheckBox *cb = wxDynamicCast(GetWindow(), wxCheckBox); \
|
||||
if(cb) \
|
||||
en = cb->GetValue(); \
|
||||
en = cb->GetValue(); \
|
||||
else { \
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton); \
|
||||
if(!rb) \
|
||||
return false; \
|
||||
en = rb->GetValue(); \
|
||||
wxRadioButton *rb = wxDynamicCast(GetWindow(), wxRadioButton); \
|
||||
if(!rb) \
|
||||
return false; \
|
||||
en = rb->GetValue(); \
|
||||
} \
|
||||
enable(controls, reverse, r ? !en : en); \
|
||||
return true; \
|
||||
|
@ -258,65 +326,71 @@ static void enable(wxWindow_v controls, std::vector<int>reverse, bool en)
|
|||
|
||||
bool wxBoolEnValidator::TransferToWindow()
|
||||
{
|
||||
if(!wxGenericValidator::TransferToWindow())
|
||||
return false;
|
||||
boolen(false);
|
||||
if (!wxGenericValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(false);
|
||||
}
|
||||
|
||||
bool wxBoolIntEnValidator::TransferToWindow()
|
||||
{
|
||||
if(!wxBoolIntValidator::TransferToWindow())
|
||||
return false;
|
||||
boolen(false);
|
||||
if (!wxBoolIntValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(false);
|
||||
}
|
||||
|
||||
bool wxBoolRevEnValidator::TransferToWindow()
|
||||
{
|
||||
if(!wxBoolRevValidator::TransferToWindow())
|
||||
return false;
|
||||
boolen(true);
|
||||
if (!wxBoolRevValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(true);
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::ToggleCheck(wxCommandEvent &ev)
|
||||
{
|
||||
enable(controls, reverse, ev.IsChecked());
|
||||
ev.Skip();
|
||||
enable(controls, reverse, ev.IsChecked());
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::Enable(wxCommandEvent &ev)
|
||||
{
|
||||
enable(controls, reverse, true);
|
||||
ev.Skip();
|
||||
enable(controls, reverse, true);
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::Disable(wxCommandEvent &ev)
|
||||
{
|
||||
enable(controls, reverse, false);
|
||||
ev.Skip();
|
||||
enable(controls, reverse, false);
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
static const wxChar * /* const */ val_hexdigits_s[] = {
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"),
|
||||
wxT("E"), wxT("F"), wxT("a"), wxT("b"), wxT("c"), wxT("d"), wxT("e"),
|
||||
wxT("f")
|
||||
static const wxChar* /* const */ val_hexdigits_s[] =
|
||||
{
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"),
|
||||
wxT("E"), wxT("F"), wxT("a"), wxT("b"), wxT("c"), wxT("d"), wxT("e"),
|
||||
wxT("f")
|
||||
};
|
||||
|
||||
const wxArrayString val_hexdigits(sizeof(val_hexdigits_s)/sizeof(val_hexdigits_s[0]),
|
||||
val_hexdigits_s);
|
||||
const wxArrayString val_hexdigits(sizeof(val_hexdigits_s) / sizeof(val_hexdigits_s[0]),
|
||||
val_hexdigits_s);
|
||||
|
||||
static const wxChar * /* const */ val_sigdigits_s[] = {
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9"), wxT("-"), wxT("+")
|
||||
static const wxChar* /* const */ val_sigdigits_s[] =
|
||||
{
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9"), wxT("-"), wxT("+")
|
||||
};
|
||||
|
||||
const wxArrayString val_sigdigits(sizeof(val_sigdigits_s)/sizeof(val_sigdigits_s[0]),
|
||||
val_sigdigits_s);
|
||||
const wxArrayString val_sigdigits(sizeof(val_sigdigits_s) / sizeof(val_sigdigits_s[0]),
|
||||
val_sigdigits_s);
|
||||
|
||||
static const wxChar * /* const */ val_unsdigits_s[] = {
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9")
|
||||
static const wxChar* /* const */ val_unsdigits_s[] =
|
||||
{
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9")
|
||||
};
|
||||
|
||||
const wxArrayString val_unsdigits(sizeof(val_unsdigits_s)/sizeof(val_unsdigits_s[0]),
|
||||
val_unsdigits_s);
|
||||
const wxArrayString val_unsdigits(sizeof(val_unsdigits_s) / sizeof(val_unsdigits_s[0]),
|
||||
val_unsdigits_s);
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
// For compilers that support precompilation, includes <wx/wx.h>.
|
||||
#include <wx/wxprec.h>
|
||||
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
|
||||
// The following are not pulled in by wx.h
|
||||
|
@ -65,28 +65,36 @@
|
|||
|
||||
#include "wx/keyedit.h"
|
||||
|
||||
static inline void DoSetAccel(wxMenuItem *mi, wxAcceleratorEntry *acc)
|
||||
static inline void DoSetAccel(wxMenuItem* mi, wxAcceleratorEntry* acc)
|
||||
{
|
||||
wxString lab = mi->GetItemLabel();
|
||||
size_t tab = lab.find(wxT('\t'));
|
||||
// following short circuit returns are to avoid UI update on no change
|
||||
if(tab == wxString::npos && !acc)
|
||||
return;
|
||||
wxString accs;
|
||||
if(acc)
|
||||
// actually, use keyedit's ToString(), as it is more reliable
|
||||
// and doesn't generate wx assertions
|
||||
// accs = acc->ToString();
|
||||
accs = wxKeyTextCtrl::ToString(acc->GetFlags(), acc->GetKeyCode());
|
||||
if(tab != wxString::npos && accs == lab.substr(tab + 1))
|
||||
return;
|
||||
if(tab != wxString::npos)
|
||||
lab.resize(tab);
|
||||
if(acc) {
|
||||
lab.append(wxT('\t'));
|
||||
lab.append(accs);
|
||||
}
|
||||
mi->SetItemLabel(lab);
|
||||
wxString lab = mi->GetItemLabel();
|
||||
size_t tab = lab.find(wxT('\t'));
|
||||
|
||||
// following short circuit returns are to avoid UI update on no change
|
||||
if (tab == wxString::npos && !acc)
|
||||
return;
|
||||
|
||||
wxString accs;
|
||||
|
||||
if (acc)
|
||||
// actually, use keyedit's ToString(), as it is more reliable
|
||||
// and doesn't generate wx assertions
|
||||
// accs = acc->ToString();
|
||||
accs = wxKeyTextCtrl::ToString(acc->GetFlags(), acc->GetKeyCode());
|
||||
|
||||
if (tab != wxString::npos && accs == lab.substr(tab + 1))
|
||||
return;
|
||||
|
||||
if (tab != wxString::npos)
|
||||
lab.resize(tab);
|
||||
|
||||
if (acc)
|
||||
{
|
||||
lab.append(wxT('\t'));
|
||||
lab.append(accs);
|
||||
}
|
||||
|
||||
mi->SetItemLabel(lab);
|
||||
}
|
||||
|
||||
// wxrc helpers (for dynamic strings instead of constant)
|
||||
|
|
1144
src/wx/wxvbam.cpp
1144
src/wx/wxvbam.cpp
File diff suppressed because it is too large
Load Diff
637
src/wx/wxvbam.h
637
src/wx/wxvbam.h
|
@ -30,11 +30,11 @@
|
|||
template <typename T>
|
||||
void CheckPointer(T pointer)
|
||||
{
|
||||
if(pointer == NULL)
|
||||
if (pointer == NULL)
|
||||
{
|
||||
std::string errormessage = "Pointer of type \"";
|
||||
errormessage+=typeid(pointer).name();
|
||||
errormessage+="\" was not correctly created.";
|
||||
errormessage += typeid(pointer).name();
|
||||
errormessage += "\" was not correctly created.";
|
||||
throw std::runtime_error(errormessage);
|
||||
}
|
||||
}
|
||||
|
@ -56,47 +56,48 @@ class MainFrame;
|
|||
class wxvbamApp : public wxApp
|
||||
{
|
||||
public:
|
||||
wxvbamApp() : wxApp(), pending_fullscreen(false) {}
|
||||
virtual bool OnInit();
|
||||
virtual void OnInitCmdLine(wxCmdLineParser &);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser &);
|
||||
// name of a file to load at earliest opportunity
|
||||
wxString pending_load;
|
||||
// list of options to set after config file loaded
|
||||
wxArrayString pending_optset;
|
||||
// set fullscreen mode after init
|
||||
bool pending_fullscreen;
|
||||
wxvbamApp() : wxApp(), pending_fullscreen(false) {}
|
||||
virtual bool OnInit();
|
||||
virtual void OnInitCmdLine(wxCmdLineParser &);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser &);
|
||||
// name of a file to load at earliest opportunity
|
||||
wxString pending_load;
|
||||
// list of options to set after config file loaded
|
||||
wxArrayString pending_optset;
|
||||
// set fullscreen mode after init
|
||||
bool pending_fullscreen;
|
||||
#if __WXMAC__
|
||||
// I suppose making this work will require tweaking the bundle
|
||||
void MacOpenFile(const wxString&f) { pending_load = f; };
|
||||
// I suppose making this work will require tweaking the bundle
|
||||
void MacOpenFile(const wxString &f) { pending_load = f; };
|
||||
#endif
|
||||
// without this, global accels don't always work
|
||||
int FilterEvent(wxEvent &event);
|
||||
wxAcceleratorEntry_v accels;
|
||||
// without this, global accels don't always work
|
||||
int FilterEvent(wxEvent &event);
|
||||
wxAcceleratorEntry_v accels;
|
||||
|
||||
// the main configuration
|
||||
wxFileConfig *cfg;
|
||||
// vba-over.ini
|
||||
wxFileConfig *overrides;
|
||||
MainFrame *frame;
|
||||
// use this to get ms since program lauch
|
||||
wxStopWatch timer;
|
||||
// append log messages to this for the log viewer
|
||||
wxString log;
|
||||
// there's no way to retrieve "current" locale, so this is public
|
||||
wxLocale locale;
|
||||
|
||||
//Handle most exceptions
|
||||
virtual bool OnExceptionInMainLoop()
|
||||
{
|
||||
// the main configuration
|
||||
wxFileConfig* cfg;
|
||||
// vba-over.ini
|
||||
wxFileConfig* overrides;
|
||||
MainFrame* frame;
|
||||
// use this to get ms since program lauch
|
||||
wxStopWatch timer;
|
||||
// append log messages to this for the log viewer
|
||||
wxString log;
|
||||
// there's no way to retrieve "current" locale, so this is public
|
||||
wxLocale locale;
|
||||
|
||||
//Handle most exceptions
|
||||
virtual bool OnExceptionInMainLoop()
|
||||
{
|
||||
try {throw;}
|
||||
catch(const std::exception& e){
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << "AN ERROR HAS OCCURRED: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
wxPathList config_path;
|
||||
wxPathList config_path;
|
||||
char* home;
|
||||
};
|
||||
|
||||
|
@ -111,51 +112,53 @@ DECLARE_APP(wxvbamApp);
|
|||
#define EVT_HANDLER_MASK(n, x, m) \
|
||||
void MainFrame::On##n(wxCommandEvent& WXUNUSED(event)) \
|
||||
{ \
|
||||
if(!(cmd_enable & (m))) \
|
||||
return; \
|
||||
Do##n(); \
|
||||
if(!(cmd_enable & (m))) \
|
||||
return; \
|
||||
Do##n(); \
|
||||
} \
|
||||
void MainFrame::Do##n() \
|
||||
|
||||
// here are those conditions
|
||||
enum {
|
||||
CMDEN_GB = (1<<0), // GB ROM loaded
|
||||
CMDEN_GBA = (1<<1), // GBA ROM loaded
|
||||
// the rest imply the above, unless:
|
||||
// _ANY -> does not imply either
|
||||
// _GBA -> only implies GBA
|
||||
CMDEN_REWIND = (1<<2), // rewind states available
|
||||
CMDEN_SREC = (1<<3), // sound recording in progress
|
||||
CMDEN_NSREC = (1<<4), // no sound recording
|
||||
CMDEN_VREC = (1<<5), // video recording
|
||||
CMDEN_NVREC = (1<<6), // no video recording
|
||||
CMDEN_GREC = (1<<7), // game recording
|
||||
CMDEN_NGREC = (1<<8), // no game recording
|
||||
CMDEN_GPLAY = (1<<9), // game playback
|
||||
CMDEN_NGPLAY = (1<<10), // no game playback
|
||||
CMDEN_SAVST = (1<<11), // any save states
|
||||
CMDEN_GDB = (1<<12), // gdb connected
|
||||
CMDEN_NGDB_GBA = (1<<13), // gdb not connected
|
||||
CMDEN_NGDB_ANY = (1<<14), // gdb not connected
|
||||
CMDEN_NREC_ANY = (1<<15), // not a/v recording
|
||||
CMDEN_LINK_ANY = (1<<16), // link enabled
|
||||
enum
|
||||
{
|
||||
CMDEN_GB = (1 << 0), // GB ROM loaded
|
||||
CMDEN_GBA = (1 << 1), // GBA ROM loaded
|
||||
// the rest imply the above, unless:
|
||||
// _ANY -> does not imply either
|
||||
// _GBA -> only implies GBA
|
||||
CMDEN_REWIND = (1 << 2), // rewind states available
|
||||
CMDEN_SREC = (1 << 3), // sound recording in progress
|
||||
CMDEN_NSREC = (1 << 4), // no sound recording
|
||||
CMDEN_VREC = (1 << 5), // video recording
|
||||
CMDEN_NVREC = (1 << 6), // no video recording
|
||||
CMDEN_GREC = (1 << 7), // game recording
|
||||
CMDEN_NGREC = (1 << 8), // no game recording
|
||||
CMDEN_GPLAY = (1 << 9), // game playback
|
||||
CMDEN_NGPLAY = (1 << 10), // no game playback
|
||||
CMDEN_SAVST = (1 << 11), // any save states
|
||||
CMDEN_GDB = (1 << 12), // gdb connected
|
||||
CMDEN_NGDB_GBA = (1 << 13), // gdb not connected
|
||||
CMDEN_NGDB_ANY = (1 << 14), // gdb not connected
|
||||
CMDEN_NREC_ANY = (1 << 15), // not a/v recording
|
||||
CMDEN_LINK_ANY = (1 << 16), // link enabled
|
||||
|
||||
CMDEN_NEVER = (1<<31) // never (for NOOP)
|
||||
CMDEN_NEVER = (1 << 31) // never (for NOOP)
|
||||
};
|
||||
#define ONLOAD_CMDEN (CMDEN_NSREC|CMDEN_NVREC|CMDEN_NGREC|CMDEN_NGPLAY)
|
||||
#define UNLOAD_CMDEN_KEEP (CMDEN_NGDB_ANY|CMDEN_NREC_ANY|CMDEN_LINK_ANY)
|
||||
|
||||
struct checkable_mi_t {
|
||||
int cmd;
|
||||
wxMenuItem *mi;
|
||||
bool *boolopt;
|
||||
int *intopt, mask, val;
|
||||
struct checkable_mi_t
|
||||
{
|
||||
int cmd;
|
||||
wxMenuItem* mi;
|
||||
bool* boolopt;
|
||||
int* intopt, mask, val;
|
||||
};
|
||||
|
||||
// wxArray is only for small types
|
||||
typedef std::vector<checkable_mi_t> checkable_mi_array_t;
|
||||
|
||||
typedef std::list<wxDialog *> dialog_list_t;
|
||||
typedef std::list<wxDialog*> dialog_list_t;
|
||||
|
||||
class GameArea;
|
||||
|
||||
|
@ -167,8 +170,8 @@ extern bool pause_next;
|
|||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
|
||||
bool BindControls();
|
||||
void MenuOptionIntMask(const char* menuName, int &field, int mask);
|
||||
|
@ -178,49 +181,49 @@ public:
|
|||
void GetMenuOptionBool(const char* menuName, bool &field);
|
||||
void SetMenuOption(const char* menuName, int value);
|
||||
|
||||
void SetJoystick();
|
||||
void SetJoystick();
|
||||
|
||||
GameArea *GetPanel() { return panel; }
|
||||
GameArea* GetPanel() { return panel; }
|
||||
|
||||
// wxMSW pauses the game for menu popups and modal dialogs, but wxGTK
|
||||
// does not. It's probably desirable to pause the game. To do this for
|
||||
// dialogs, use this function instead of dlg->ShowModal()
|
||||
int ShowModal(wxDialog *dlg);
|
||||
// and here are the wrapper functions for use when ShowModal() isn't
|
||||
// possible
|
||||
void StartModal();
|
||||
void StopModal();
|
||||
// however, adding a handler for open/close menu to do the same is unsafe.
|
||||
// there is no guarantee every show will be matched by a hide.
|
||||
void MenuPopped(wxMenuEvent &evt);
|
||||
// wxMSW pauses the game for menu popups and modal dialogs, but wxGTK
|
||||
// does not. It's probably desirable to pause the game. To do this for
|
||||
// dialogs, use this function instead of dlg->ShowModal()
|
||||
int ShowModal(wxDialog* dlg);
|
||||
// and here are the wrapper functions for use when ShowModal() isn't
|
||||
// possible
|
||||
void StartModal();
|
||||
void StopModal();
|
||||
// however, adding a handler for open/close menu to do the same is unsafe.
|
||||
// there is no guarantee every show will be matched by a hide.
|
||||
void MenuPopped(wxMenuEvent &evt);
|
||||
|
||||
// flags for enabling commands
|
||||
int cmd_enable;
|
||||
// flags for enabling commands
|
||||
int cmd_enable;
|
||||
|
||||
// adjust menus based on current cmd_enable
|
||||
void enable_menus();
|
||||
// adjust menus based on current cmd_enable
|
||||
void enable_menus();
|
||||
void EnableNetworkMenu();
|
||||
|
||||
// adjust menus based on available save game states
|
||||
void update_state_ts(bool force = false);
|
||||
// adjust menus based on available save game states
|
||||
void update_state_ts(bool force = false);
|
||||
|
||||
// retrieve oldest/newest slot
|
||||
// returns lowest-numbered slot on ties
|
||||
int oldest_state_slot(); // or empty slot if available
|
||||
int newest_state_slot(); // or 0 if none
|
||||
// retrieve oldest/newest slot
|
||||
// returns lowest-numbered slot on ties
|
||||
int oldest_state_slot(); // or empty slot if available
|
||||
int newest_state_slot(); // or 0 if none
|
||||
|
||||
// system-defined accelerators
|
||||
wxAcceleratorEntry_v sys_accels;
|
||||
// adjust recent menu with accelerators
|
||||
void SetRecentAccels();
|
||||
// merge sys accels with user-defined accels (user overrides sys)
|
||||
wxAcceleratorEntry_v get_accels(wxAcceleratorEntry_v user_accels);
|
||||
// update menu and global accelerator table with sys+user accel defs
|
||||
// probably not the quickest way to add/remove individual accels
|
||||
void set_global_accels();
|
||||
// system-defined accelerators
|
||||
wxAcceleratorEntry_v sys_accels;
|
||||
// adjust recent menu with accelerators
|
||||
void SetRecentAccels();
|
||||
// merge sys accels with user-defined accels (user overrides sys)
|
||||
wxAcceleratorEntry_v get_accels(wxAcceleratorEntry_v user_accels);
|
||||
// update menu and global accelerator table with sys+user accel defs
|
||||
// probably not the quickest way to add/remove individual accels
|
||||
void set_global_accels();
|
||||
|
||||
// 2.8 has no HasFocus(), and FindFocus() doesn't work right
|
||||
bool HasFocus() { return focused; }
|
||||
// 2.8 has no HasFocus(), and FindFocus() doesn't work right
|
||||
bool HasFocus() { return focused; }
|
||||
|
||||
// Returns the link mode to set according to the options
|
||||
LinkMode GetConfiguredLinkMode();
|
||||
|
@ -228,77 +231,77 @@ public:
|
|||
// Start GDB listener
|
||||
void GDBBreak();
|
||||
|
||||
// The various viewer popups; these can be popped up as often as
|
||||
// desired
|
||||
void Disassemble();
|
||||
void IOViewer();
|
||||
void MapViewer();
|
||||
void MemViewer();
|
||||
void OAMViewer();
|
||||
void PaletteViewer();
|
||||
void TileViewer();
|
||||
// The various viewer popups; these can be popped up as often as
|
||||
// desired
|
||||
void Disassemble();
|
||||
void IOViewer();
|
||||
void MapViewer();
|
||||
void MemViewer();
|
||||
void OAMViewer();
|
||||
void PaletteViewer();
|
||||
void TileViewer();
|
||||
|
||||
// since they will all have to be destroyed on game unload:
|
||||
dialog_list_t popups;
|
||||
// since they will all have to be destroyed on game unload:
|
||||
dialog_list_t popups;
|
||||
|
||||
// this won't actually be destroyed, but it needs to be tracked so only
|
||||
// one is ever up and it needs to be pinged when new messages arrive
|
||||
LogDialog *logdlg;
|
||||
// this won't actually be destroyed, but it needs to be tracked so only
|
||||
// one is ever up and it needs to be pinged when new messages arrive
|
||||
LogDialog* logdlg;
|
||||
|
||||
// the cheat search dialog isn't destroyed or tracked, but it needs
|
||||
// to be cleared between games
|
||||
void ResetCheatSearch();
|
||||
|
||||
// call this to update the viewers once a frame:
|
||||
void UpdateViewers();
|
||||
// the cheat search dialog isn't destroyed or tracked, but it needs
|
||||
// to be cleared between games
|
||||
void ResetCheatSearch();
|
||||
|
||||
// required for building from xrc
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
// required for event handling
|
||||
DECLARE_EVENT_TABLE();
|
||||
// call this to update the viewers once a frame:
|
||||
void UpdateViewers();
|
||||
|
||||
// required for building from xrc
|
||||
DECLARE_DYNAMIC_CLASS();
|
||||
// required for event handling
|
||||
DECLARE_EVENT_TABLE();
|
||||
private:
|
||||
GameArea *panel;
|
||||
GameArea* panel;
|
||||
|
||||
// the various reasons the game might be paused
|
||||
bool paused;
|
||||
int menus_opened, dialog_opened;
|
||||
// the various reasons the game might be paused
|
||||
bool paused;
|
||||
int menus_opened, dialog_opened;
|
||||
public:
|
||||
bool IsPaused(bool incendental = false)
|
||||
{
|
||||
return (paused && !pause_next && !incendental) || menus_opened || dialog_opened;
|
||||
}
|
||||
bool IsPaused(bool incendental = false)
|
||||
{
|
||||
return (paused && !pause_next && !incendental) || menus_opened || dialog_opened;
|
||||
}
|
||||
private:
|
||||
|
||||
bool autoLoadMostRecent;
|
||||
// copy of top-level menu bar as a context menu
|
||||
wxMenu *ctx_menu;
|
||||
// load/save states menu items
|
||||
wxMenuItem *loadst_mi[10];
|
||||
wxMenuItem *savest_mi[10];
|
||||
wxDateTime state_ts[10];
|
||||
// checkable menu items
|
||||
checkable_mi_array_t checkable_mi;
|
||||
// recent menu item accels
|
||||
wxMenu *recent;
|
||||
wxAcceleratorEntry recent_accel[10];
|
||||
// joystick reader
|
||||
wxSDLJoy joy;
|
||||
bool autoLoadMostRecent;
|
||||
// copy of top-level menu bar as a context menu
|
||||
wxMenu* ctx_menu;
|
||||
// load/save states menu items
|
||||
wxMenuItem* loadst_mi[10];
|
||||
wxMenuItem* savest_mi[10];
|
||||
wxDateTime state_ts[10];
|
||||
// checkable menu items
|
||||
checkable_mi_array_t checkable_mi;
|
||||
// recent menu item accels
|
||||
wxMenu* recent;
|
||||
wxAcceleratorEntry recent_accel[10];
|
||||
// joystick reader
|
||||
wxSDLJoy joy;
|
||||
|
||||
// helper function for adding menu to accel editor
|
||||
void add_menu_accels(wxTreeCtrl *tc, wxTreeItemId &parent, wxMenu *menu);
|
||||
// helper function for adding menu to accel editor
|
||||
void add_menu_accels(wxTreeCtrl* tc, wxTreeItemId &parent, wxMenu* menu);
|
||||
|
||||
// for detecting window focus
|
||||
void OnActivate(wxActivateEvent&);
|
||||
// quicker & more accurate than FindFocus() != NULL
|
||||
bool focused;
|
||||
// may work, may not... if so, load dropped file
|
||||
void OnDropFile(wxDropFilesEvent&);
|
||||
// pop up menu in fullscreen mode
|
||||
void OnMenu(wxContextMenuEvent &);
|
||||
// Load a named wxDialog from the XRC file
|
||||
wxDialog * LoadXRCDialog(const char * name);
|
||||
// Load a named wxDialog from the XRC file
|
||||
wxDialog * LoadXRCropertySheetDialog(const char * name);
|
||||
// for detecting window focus
|
||||
void OnActivate(wxActivateEvent &);
|
||||
// quicker & more accurate than FindFocus() != NULL
|
||||
bool focused;
|
||||
// may work, may not... if so, load dropped file
|
||||
void OnDropFile(wxDropFilesEvent &);
|
||||
// pop up menu in fullscreen mode
|
||||
void OnMenu(wxContextMenuEvent &);
|
||||
// Load a named wxDialog from the XRC file
|
||||
wxDialog* LoadXRCDialog(const char* name);
|
||||
// Load a named wxDialog from the XRC file
|
||||
wxDialog* LoadXRCropertySheetDialog(const char* name);
|
||||
#include "cmdhandlers.h"
|
||||
};
|
||||
|
||||
|
@ -306,41 +309,46 @@ private:
|
|||
class ModalPause
|
||||
{
|
||||
public:
|
||||
ModalPause() { wxGetApp().frame->StartModal(); }
|
||||
~ModalPause() { wxGetApp().frame->StopModal(); }
|
||||
ModalPause() { wxGetApp().frame->StartModal(); }
|
||||
~ModalPause() { wxGetApp().frame->StopModal(); }
|
||||
};
|
||||
|
||||
enum showspeed {
|
||||
// this order must match order of option enum and selector widget
|
||||
SS_NONE, SS_PERCENT, SS_DETAILED
|
||||
enum showspeed
|
||||
{
|
||||
// this order must match order of option enum and selector widget
|
||||
SS_NONE, SS_PERCENT, SS_DETAILED
|
||||
};
|
||||
|
||||
enum filtfunc {
|
||||
// this order must match order of option enum and selector widget
|
||||
FF_NONE, FF_2XSAI, FF_SUPER2XSAI, FF_SUPEREAGLE, FF_PIXELATE,
|
||||
FF_ADVMAME, FF_BILINEAR, FF_BILINEARPLUS, FF_SCANLINES, FF_TV,
|
||||
FF_HQ2X, FF_LQ2X, FF_SIMPLE2X, FF_SIMPLE3X, FF_HQ3X, FF_SIMPLE4X,
|
||||
enum filtfunc
|
||||
{
|
||||
// this order must match order of option enum and selector widget
|
||||
FF_NONE, FF_2XSAI, FF_SUPER2XSAI, FF_SUPEREAGLE, FF_PIXELATE,
|
||||
FF_ADVMAME, FF_BILINEAR, FF_BILINEARPLUS, FF_SCANLINES, FF_TV,
|
||||
FF_HQ2X, FF_LQ2X, FF_SIMPLE2X, FF_SIMPLE3X, FF_HQ3X, FF_SIMPLE4X,
|
||||
FF_HQ4X, FF_XBRZ2X, FF_XBRZ3X, FF_XBRZ4X, FF_XBRZ5X, FF_PLUGIN // plugin must always be last
|
||||
};
|
||||
#define builtin_ff_scale(x) \
|
||||
((x == FF_XBRZ5X) ? 5 : \
|
||||
((x == FF_XBRZ5X) ? 5 : \
|
||||
(x == FF_XBRZ4X || x == FF_HQ4X || x == FF_SIMPLE4X) ? 4 : \
|
||||
(x == FF_XBRZ3X || x == FF_HQ3X || x == FF_SIMPLE3X) ? 3 : \
|
||||
x == FF_PLUGIN ? 0 : x == FF_NONE ? 1 : 2)
|
||||
(x == FF_XBRZ3X || x == FF_HQ3X || x == FF_SIMPLE3X) ? 3 : \
|
||||
x == FF_PLUGIN ? 0 : x == FF_NONE ? 1 : 2)
|
||||
|
||||
enum ifbfunc {
|
||||
// this order must match order of option enum and selector widget
|
||||
IFB_NONE, IFB_SMART, IFB_MOTION_BLUR
|
||||
enum ifbfunc
|
||||
{
|
||||
// this order must match order of option enum and selector widget
|
||||
IFB_NONE, IFB_SMART, IFB_MOTION_BLUR
|
||||
};
|
||||
|
||||
// make sure and keep this in sync with opts.cpp!
|
||||
enum renderer {
|
||||
RND_SIMPLE, RND_OPENGL, RND_CAIRO, RND_DIRECT3D
|
||||
enum renderer
|
||||
{
|
||||
RND_SIMPLE, RND_OPENGL, RND_CAIRO, RND_DIRECT3D
|
||||
};
|
||||
|
||||
// likewise
|
||||
enum audioapi {
|
||||
AUD_SDL, AUD_OPENAL, AUD_DIRECTSOUND, AUD_XAUDIO2
|
||||
enum audioapi
|
||||
{
|
||||
AUD_SDL, AUD_OPENAL, AUD_DIRECTSOUND, AUD_XAUDIO2
|
||||
};
|
||||
|
||||
// an unfortunate legacy default; should have a non-digit preceding %d
|
||||
|
@ -359,125 +367,125 @@ class DrawingPanel;
|
|||
class GameArea : public wxPanel
|
||||
{
|
||||
public:
|
||||
GameArea();
|
||||
virtual ~GameArea();
|
||||
GameArea();
|
||||
virtual ~GameArea();
|
||||
|
||||
// set to game title + link info
|
||||
void SetFrameTitle();
|
||||
// set to game title + link info
|
||||
void SetFrameTitle();
|
||||
|
||||
void LoadGame(const wxString &name);
|
||||
void UnloadGame(bool destruct = false);
|
||||
void LoadGame(const wxString &name);
|
||||
void UnloadGame(bool destruct = false);
|
||||
|
||||
IMAGE_TYPE game_type() { return loaded; }
|
||||
u32 game_size() { return rom_size; }
|
||||
wxString game_dir() { return loaded_game.GetPath(); }
|
||||
wxString game_name() { return loaded_game.GetFullName(); }
|
||||
wxString bat_dir() { return batdir; }
|
||||
wxString state_dir() { return statedir; }
|
||||
void recompute_dirs();
|
||||
IMAGE_TYPE game_type() { return loaded; }
|
||||
u32 game_size() { return rom_size; }
|
||||
wxString game_dir() { return loaded_game.GetPath(); }
|
||||
wxString game_name() { return loaded_game.GetFullName(); }
|
||||
wxString bat_dir() { return batdir; }
|
||||
wxString state_dir() { return statedir; }
|
||||
void recompute_dirs();
|
||||
|
||||
bool LoadState();
|
||||
bool LoadState(int slot);
|
||||
bool LoadState(const wxFileName &fname);
|
||||
bool LoadState();
|
||||
bool LoadState(int slot);
|
||||
bool LoadState(const wxFileName &fname);
|
||||
|
||||
bool SaveState();
|
||||
bool SaveState(int slot);
|
||||
bool SaveState(const wxFileName &fname);
|
||||
bool SaveState();
|
||||
bool SaveState(int slot);
|
||||
bool SaveState(const wxFileName &fname);
|
||||
|
||||
// save to default location
|
||||
void SaveBattery(bool quiet = false);
|
||||
// save to default location
|
||||
void SaveBattery(bool quiet = false);
|
||||
|
||||
// true if file at default location may not match memory
|
||||
bool cheats_dirty;
|
||||
// true if file at default location may not match memory
|
||||
bool cheats_dirty;
|
||||
|
||||
static const int GBWidth = 160, GBHeight = 144,
|
||||
SGBWidth = 256, SGBHeight = 224,
|
||||
GBAWidth = 240, GBAHeight = 160;
|
||||
void AddBorder();
|
||||
void DelBorder();
|
||||
// Delete() & set to NULL to force reinit
|
||||
DrawingPanel *panel;
|
||||
struct EmulatedSystem *emusys;
|
||||
static const int GBWidth = 160, GBHeight = 144,
|
||||
SGBWidth = 256, SGBHeight = 224,
|
||||
GBAWidth = 240, GBAHeight = 160;
|
||||
void AddBorder();
|
||||
void DelBorder();
|
||||
// Delete() & set to NULL to force reinit
|
||||
DrawingPanel* panel;
|
||||
struct EmulatedSystem* emusys;
|
||||
|
||||
// pause game or signal a long operation, similar to pausing
|
||||
void Pause();
|
||||
void Resume();
|
||||
// pause game or signal a long operation, similar to pausing
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
// true if paused since last reset of flag
|
||||
bool was_paused;
|
||||
// true if paused since last reset of flag
|
||||
bool was_paused;
|
||||
|
||||
// osdstat is always displayed at top-left of screen
|
||||
wxString osdstat;
|
||||
// osdstat is always displayed at top-left of screen
|
||||
wxString osdstat;
|
||||
|
||||
// osdtext is displayed for 3 seconds after osdtime, and then cleared
|
||||
wxString osdtext;
|
||||
u32 osdtime;
|
||||
// osdtext is displayed for 3 seconds after osdtime, and then cleared
|
||||
wxString osdtext;
|
||||
u32 osdtime;
|
||||
|
||||
// Rewind: count down to 0 and rewind
|
||||
u32 rewind_time;
|
||||
// Rewind: flag to OnIdle to do a rewind
|
||||
bool do_rewind;
|
||||
// Rewind: rewind states
|
||||
char *rewind_mem; // should be u8, really
|
||||
int num_rewind_states;
|
||||
int next_rewind_state;
|
||||
// FIXME: size this properly
|
||||
// Rewind: count down to 0 and rewind
|
||||
u32 rewind_time;
|
||||
// Rewind: flag to OnIdle to do a rewind
|
||||
bool do_rewind;
|
||||
// Rewind: rewind states
|
||||
char* rewind_mem; // should be u8, really
|
||||
int num_rewind_states;
|
||||
int next_rewind_state;
|
||||
// FIXME: size this properly
|
||||
#define REWIND_SIZE 400000
|
||||
// FIXME: make this a config option
|
||||
// FIXME: make this a config option
|
||||
#define NUM_REWINDS 8
|
||||
|
||||
void ShowFullScreen(bool full);
|
||||
bool IsFullScreen() { return fullscreen; }
|
||||
// set size of frame & panel to scaled screen size
|
||||
void AdjustSize(bool force);
|
||||
void ShowFullScreen(bool full);
|
||||
bool IsFullScreen() { return fullscreen; }
|
||||
// set size of frame & panel to scaled screen size
|
||||
void AdjustSize(bool force);
|
||||
#ifndef NO_FFMPEG
|
||||
void StartSoundRecording(const wxString &fname);
|
||||
void StopSoundRecording();
|
||||
void StartVidRecording(const wxString &fname);
|
||||
void StopVidRecording();
|
||||
void AddFrame(const u8 *data); // video
|
||||
void AddFrame(const u16 *data, int length); // audio
|
||||
bool IsRecording() { return snd_rec.IsRecording() || vid_rec.IsRecording(); }
|
||||
void StartSoundRecording(const wxString &fname);
|
||||
void StopSoundRecording();
|
||||
void StartVidRecording(const wxString &fname);
|
||||
void StopVidRecording();
|
||||
void AddFrame(const u8* data); // video
|
||||
void AddFrame(const u16* data, int length); // audio
|
||||
bool IsRecording() { return snd_rec.IsRecording() || vid_rec.IsRecording(); }
|
||||
#endif
|
||||
void StartGameRecording(const wxString &fname);
|
||||
void StopGameRecording();
|
||||
void StartGamePlayback(const wxString &fname);
|
||||
void StopGamePlayback();
|
||||
void StartGameRecording(const wxString &fname);
|
||||
void StopGameRecording();
|
||||
void StartGamePlayback(const wxString &fname);
|
||||
void StopGamePlayback();
|
||||
|
||||
protected:
|
||||
// set minsize of frame & panel to unscaled screen size
|
||||
void LowerMinSize();
|
||||
// set minsize of frame & panel to scaled screen size
|
||||
void AdjustMinSize();
|
||||
// set minsize of frame & panel to unscaled screen size
|
||||
void LowerMinSize();
|
||||
// set minsize of frame & panel to scaled screen size
|
||||
void AdjustMinSize();
|
||||
|
||||
IMAGE_TYPE loaded;
|
||||
u32 rom_size;
|
||||
wxFileName loaded_game;
|
||||
wxString batdir, statedir;
|
||||
IMAGE_TYPE loaded;
|
||||
u32 rom_size;
|
||||
wxFileName loaded_game;
|
||||
wxString batdir, statedir;
|
||||
|
||||
int basic_width, basic_height;
|
||||
bool fullscreen;
|
||||
int basic_width, basic_height;
|
||||
bool fullscreen;
|
||||
|
||||
bool paused;
|
||||
void OnIdle(wxIdleEvent &);
|
||||
void OnKeyDown(wxKeyEvent &ev);
|
||||
void OnKeyUp(wxKeyEvent &ev);
|
||||
void OnSDLJoy(wxSDLJoyEvent &ev);
|
||||
bool paused;
|
||||
void OnIdle(wxIdleEvent &);
|
||||
void OnKeyDown(wxKeyEvent &ev);
|
||||
void OnKeyUp(wxKeyEvent &ev);
|
||||
void OnSDLJoy(wxSDLJoyEvent &ev);
|
||||
|
||||
#ifndef NO_FFMPEG
|
||||
MediaRecorder snd_rec, vid_rec;
|
||||
MediaRecorder snd_rec, vid_rec;
|
||||
#endif
|
||||
|
||||
public:
|
||||
void ShowPointer();
|
||||
void HidePointer();
|
||||
void ShowPointer();
|
||||
void HidePointer();
|
||||
protected:
|
||||
void MouseEvent(wxMouseEvent &) { ShowPointer(); }
|
||||
bool pointer_blanked;
|
||||
u32 mouse_active_time;
|
||||
void MouseEvent(wxMouseEvent &) { ShowPointer(); }
|
||||
bool pointer_blanked;
|
||||
u32 mouse_active_time;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
// wxString version of OSD message
|
||||
|
@ -486,12 +494,13 @@ void systemScreenMessage(const wxString &msg);
|
|||
// List of all commands with their descriptions
|
||||
// sorted by cmd field for binary searching
|
||||
// filled in by copy-events.cmake
|
||||
extern struct cmditem {
|
||||
const wxChar *cmd, *name;
|
||||
int cmd_id;
|
||||
int mask_flags; // if non-0, one of the flags must be turned on in win
|
||||
// to enable this command
|
||||
wxMenuItem *mi; // the menu item to invoke command, if present
|
||||
extern struct cmditem
|
||||
{
|
||||
const wxChar* cmd, *name;
|
||||
int cmd_id;
|
||||
int mask_flags; // if non-0, one of the flags must be turned on in win
|
||||
// to enable this command
|
||||
wxMenuItem* mi; // the menu item to invoke command, if present
|
||||
} cmdtab[];
|
||||
extern const int ncmds;
|
||||
// for binary search
|
||||
|
@ -505,72 +514,72 @@ class FilterThread;
|
|||
class DrawingPanel : public wxObject
|
||||
{
|
||||
public:
|
||||
DrawingPanel(int _width, int _height);
|
||||
~DrawingPanel();
|
||||
void DrawArea(u8 **pixels);
|
||||
// the following wouldn't be necessary with virtual inheritance
|
||||
virtual wxWindow *GetWindow() = 0;
|
||||
virtual void Delete() = 0;
|
||||
DrawingPanel(int _width, int _height);
|
||||
~DrawingPanel();
|
||||
void DrawArea(u8** pixels);
|
||||
// the following wouldn't be necessary with virtual inheritance
|
||||
virtual wxWindow* GetWindow() = 0;
|
||||
virtual void Delete() = 0;
|
||||
|
||||
protected:
|
||||
virtual void DrawArea(wxWindowDC&) = 0;
|
||||
virtual void DrawOSD(wxWindowDC&);
|
||||
int width, height, scale;
|
||||
u8 *todraw;
|
||||
u8 *pixbuf1, *pixbuf2;
|
||||
FilterThread *threads;
|
||||
int nthreads;
|
||||
wxSemaphore filt_done;
|
||||
wxDynamicLibrary filt_plugin;
|
||||
const RENDER_PLUGIN_INFO *rpi; // also flag indicating plugin loaded
|
||||
// largest buffer required is 32-bit * (max width + 1) * (max height + 2)
|
||||
u8 delta[257 * 4 * 226];
|
||||
virtual void DrawArea(wxWindowDC &) = 0;
|
||||
virtual void DrawOSD(wxWindowDC &);
|
||||
int width, height, scale;
|
||||
u8* todraw;
|
||||
u8* pixbuf1, *pixbuf2;
|
||||
FilterThread* threads;
|
||||
int nthreads;
|
||||
wxSemaphore filt_done;
|
||||
wxDynamicLibrary filt_plugin;
|
||||
const RENDER_PLUGIN_INFO* rpi; // also flag indicating plugin loaded
|
||||
// largest buffer required is 32-bit * (max width + 1) * (max height + 2)
|
||||
u8 delta[257 * 4 * 226];
|
||||
|
||||
// following can't work in 2.8 as intended
|
||||
// inheriting from wxEvtHandler is required, but also breaks subclasses
|
||||
// due to lack of virtual inheritance (2.9 drops wxEvtHandler req)
|
||||
// so each child must have a paint event handler (not override of this,
|
||||
// but it's not virtual anyway, so that won't happen) that calls this
|
||||
void PaintEv(wxPaintEvent &ev);
|
||||
// following can't work in 2.8 as intended
|
||||
// inheriting from wxEvtHandler is required, but also breaks subclasses
|
||||
// due to lack of virtual inheritance (2.9 drops wxEvtHandler req)
|
||||
// so each child must have a paint event handler (not override of this,
|
||||
// but it's not virtual anyway, so that won't happen) that calls this
|
||||
void PaintEv(wxPaintEvent &ev);
|
||||
|
||||
DECLARE_ABSTRACT_CLASS()
|
||||
DECLARE_ABSTRACT_CLASS()
|
||||
};
|
||||
|
||||
class LogDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
LogDialog();
|
||||
void Update();
|
||||
LogDialog();
|
||||
void Update();
|
||||
private:
|
||||
wxTextCtrl *log;
|
||||
void Save(wxCommandEvent &ev);
|
||||
void Clear(wxCommandEvent &ev);
|
||||
wxTextCtrl* log;
|
||||
void Save(wxCommandEvent &ev);
|
||||
void Clear(wxCommandEvent &ev);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#include "opts.h"
|
||||
|
||||
class SoundDriver;
|
||||
extern SoundDriver *newOpenAL();
|
||||
extern SoundDriver* newOpenAL();
|
||||
// I should add this to SoundDriver, but wxArrayString is wx-specific
|
||||
// I suppose I could make subclass wxSoundDriver. maybe later.
|
||||
extern bool GetOALDevices(wxArrayString &names, wxArrayString &ids);
|
||||
#ifdef __WXMSW__
|
||||
extern SoundDriver *newDirectSound();
|
||||
extern SoundDriver* newDirectSound();
|
||||
extern bool GetDSDevices(wxArrayString &names, wxArrayString &ids);
|
||||
extern SoundDriver *newXAudio2_Output();
|
||||
extern SoundDriver* newXAudio2_Output();
|
||||
extern bool GetXA2Devices(wxArrayString &names, wxArrayString &ids);
|
||||
#endif
|
||||
|
||||
extern bool debugger;
|
||||
extern void (*dbgMain)();
|
||||
extern void (*dbgSignal)(int, int);
|
||||
extern void (*dbgOutput)(const char *, u32);
|
||||
extern void (*dbgOutput)(const char*, u32);
|
||||
extern void remoteStubMain();
|
||||
extern void remoteCleanUp();
|
||||
extern void remoteStubSignal(int, int);
|
||||
extern void remoteOutput(const char *, u32);
|
||||
extern void remoteOutput(const char*, u32);
|
||||
|
||||
extern bool debugOpenPty();
|
||||
extern const wxString &debugGetSlavePty();
|
||||
|
|
|
@ -20,57 +20,73 @@
|
|||
#include "../System.h" // for systemMessage()
|
||||
#include "../gba/Globals.h"
|
||||
|
||||
int GetXA2Devices(IXAudio2 *xa, wxArrayString *names, wxArrayString *ids,
|
||||
const wxString *match)
|
||||
int GetXA2Devices(IXAudio2* xa, wxArrayString* names, wxArrayString* ids,
|
||||
const wxString* match)
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT32 dev_count = 0;
|
||||
hr = xa->GetDeviceCount( &dev_count );
|
||||
if( hr != S_OK ) {
|
||||
hr = xa->GetDeviceCount(&dev_count);
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("XAudio2: Enumerating devices failed!"));
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
XAUDIO2_DEVICE_DETAILS dd;
|
||||
for( UINT32 i = 0; i < dev_count; i++ ) {
|
||||
hr = xa->GetDeviceDetails( i, &dd );
|
||||
if( hr != S_OK ) {
|
||||
|
||||
for (UINT32 i = 0; i < dev_count; i++)
|
||||
{
|
||||
hr = xa->GetDeviceDetails(i, &dd);
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
continue;
|
||||
} else {
|
||||
if(ids) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ids)
|
||||
{
|
||||
ids->push_back(dd.DeviceID);
|
||||
names->push_back( dd.DisplayName );
|
||||
} else if(*match == dd.DeviceID)
|
||||
names->push_back(dd.DisplayName);
|
||||
}
|
||||
else if (*match == dd.DeviceID)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool GetXA2Devices(wxArrayString &names, wxArrayString &ids)
|
||||
{
|
||||
HRESULT hr;
|
||||
IXAudio2 *xa = NULL;
|
||||
IXAudio2* xa = NULL;
|
||||
UINT32 flags = 0;
|
||||
#ifdef _DEBUG
|
||||
flags = XAUDIO2_DEBUG_ENGINE;
|
||||
#endif
|
||||
hr = XAudio2Create(&xa, flags);
|
||||
|
||||
hr = XAudio2Create( &xa, flags );
|
||||
if( hr != S_OK ) {
|
||||
wxLogError( _("The XAudio2 interface failed to initialize!") );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("The XAudio2 interface failed to initialize!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
GetXA2Devices(xa, &names, &ids, NULL);
|
||||
xa->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
static int XA2GetDev(IXAudio2 *xa)
|
||||
static int XA2GetDev(IXAudio2* xa)
|
||||
{
|
||||
if(gopts.audio_dev.empty())
|
||||
if (gopts.audio_dev.empty())
|
||||
return 0;
|
||||
else {
|
||||
else
|
||||
{
|
||||
int ret = GetXA2Devices(xa, NULL, NULL, &gopts.audio_dev);
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
|
@ -79,12 +95,12 @@ static int XA2GetDev(IXAudio2 *xa)
|
|||
|
||||
class XAudio2_Output;
|
||||
|
||||
static void xaudio2_device_changed( XAudio2_Output * );
|
||||
static void xaudio2_device_changed(XAudio2_Output*);
|
||||
|
||||
class XAudio2_Device_Notifier : public IMMNotificationClient
|
||||
{
|
||||
volatile LONG registered;
|
||||
IMMDeviceEnumerator *pEnumerator;
|
||||
IMMDeviceEnumerator* pEnumerator;
|
||||
|
||||
std::wstring last_device;
|
||||
|
||||
|
@ -92,13 +108,13 @@ class XAudio2_Device_Notifier : public IMMNotificationClient
|
|||
std::vector<XAudio2_Output*> instances;
|
||||
|
||||
public:
|
||||
XAudio2_Device_Notifier() : registered( 0 )
|
||||
XAudio2_Device_Notifier() : registered(0)
|
||||
{
|
||||
InitializeCriticalSection( &lock );
|
||||
InitializeCriticalSection(&lock);
|
||||
}
|
||||
~XAudio2_Device_Notifier()
|
||||
{
|
||||
DeleteCriticalSection( &lock );
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
|
@ -111,7 +127,7 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, VOID **ppvInterface )
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface)
|
||||
{
|
||||
if (IID_IUnknown == riid)
|
||||
{
|
||||
|
@ -126,70 +142,75 @@ public:
|
|||
*ppvInterface = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged( EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId )
|
||||
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
|
||||
{
|
||||
if ( flow == eRender && last_device.compare( pwstrDeviceId ) != 0 )
|
||||
if (flow == eRender && last_device.compare(pwstrDeviceId) != 0)
|
||||
{
|
||||
last_device = pwstrDeviceId;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
EnterCriticalSection( &lock );
|
||||
for ( auto it = instances.begin(); it < instances.end(); ++it )
|
||||
for (auto it = instances.begin(); it < instances.end(); ++it)
|
||||
{
|
||||
xaudio2_device_changed( *it );
|
||||
xaudio2_device_changed(*it);
|
||||
}
|
||||
LeaveCriticalSection( &lock );
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceAdded( LPCWSTR pwstrDeviceId ) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceRemoved( LPCWSTR pwstrDeviceId ) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged( LPCWSTR pwstrDeviceId, DWORD dwNewState ) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged( LPCWSTR pwstrDeviceId, const PROPERTYKEY key ) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { return S_OK; }
|
||||
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { return S_OK; }
|
||||
|
||||
void do_register(XAudio2_Output * p_instance)
|
||||
void do_register(XAudio2_Output* p_instance)
|
||||
{
|
||||
if ( InterlockedIncrement( ®istered ) == 1 )
|
||||
if (InterlockedIncrement(®istered) == 1)
|
||||
{
|
||||
pEnumerator = NULL;
|
||||
HRESULT hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, CLSCTX_INPROC_SERVER, __uuidof( IMMDeviceEnumerator ), ( void** ) &pEnumerator );
|
||||
if ( SUCCEEDED( hr ) )
|
||||
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**) &pEnumerator);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pEnumerator->RegisterEndpointNotificationCallback( this );
|
||||
pEnumerator->RegisterEndpointNotificationCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection( &lock );
|
||||
instances.push_back( p_instance );
|
||||
LeaveCriticalSection( &lock );
|
||||
EnterCriticalSection(&lock);
|
||||
instances.push_back(p_instance);
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
void do_unregister( XAudio2_Output * p_instance )
|
||||
void do_unregister(XAudio2_Output* p_instance)
|
||||
{
|
||||
if ( InterlockedDecrement( ®istered ) == 0 )
|
||||
if (InterlockedDecrement(®istered) == 0)
|
||||
{
|
||||
if (pEnumerator)
|
||||
{
|
||||
pEnumerator->UnregisterEndpointNotificationCallback( this );
|
||||
pEnumerator->UnregisterEndpointNotificationCallback(this);
|
||||
pEnumerator->Release();
|
||||
pEnumerator = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection( &lock );
|
||||
for ( auto it = instances.begin(); it < instances.end(); ++it )
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
for (auto it = instances.begin(); it < instances.end(); ++it)
|
||||
{
|
||||
if ( *it == p_instance )
|
||||
if (*it == p_instance)
|
||||
{
|
||||
instances.erase( it );
|
||||
instances.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &lock );
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
} g_notifier;
|
||||
|
||||
|
@ -199,30 +220,33 @@ class XAudio2_BufferNotify : public IXAudio2VoiceCallback
|
|||
public:
|
||||
HANDLE hBufferEndEvent;
|
||||
|
||||
XAudio2_BufferNotify() {
|
||||
XAudio2_BufferNotify()
|
||||
{
|
||||
hBufferEndEvent = NULL;
|
||||
hBufferEndEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
assert( hBufferEndEvent != NULL );
|
||||
hBufferEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
assert(hBufferEndEvent != NULL);
|
||||
}
|
||||
|
||||
~XAudio2_BufferNotify() {
|
||||
CloseHandle( hBufferEndEvent );
|
||||
~XAudio2_BufferNotify()
|
||||
{
|
||||
CloseHandle(hBufferEndEvent);
|
||||
hBufferEndEvent = NULL;
|
||||
}
|
||||
|
||||
STDMETHOD_( void, OnBufferEnd ) ( void *pBufferContext ) {
|
||||
assert( hBufferEndEvent != NULL );
|
||||
SetEvent( hBufferEndEvent );
|
||||
STDMETHOD_(void, OnBufferEnd)(void* pBufferContext)
|
||||
{
|
||||
assert(hBufferEndEvent != NULL);
|
||||
SetEvent(hBufferEndEvent);
|
||||
}
|
||||
|
||||
|
||||
// dummies:
|
||||
STDMETHOD_( void, OnVoiceProcessingPassStart ) ( UINT32 BytesRequired ) {}
|
||||
STDMETHOD_( void, OnVoiceProcessingPassEnd ) () {}
|
||||
STDMETHOD_( void, OnStreamEnd ) () {}
|
||||
STDMETHOD_( void, OnBufferStart ) ( void *pBufferContext ) {}
|
||||
STDMETHOD_( void, OnLoopEnd ) ( void *pBufferContext ) {}
|
||||
STDMETHOD_( void, OnVoiceError ) ( void *pBufferContext, HRESULT Error ) {};
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32 BytesRequired) {}
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd)() {}
|
||||
STDMETHOD_(void, OnStreamEnd)() {}
|
||||
STDMETHOD_(void, OnBufferStart)(void* pBufferContext) {}
|
||||
STDMETHOD_(void, OnLoopEnd)(void* pBufferContext) {}
|
||||
STDMETHOD_(void, OnVoiceError)(void* pBufferContext, HRESULT Error) {};
|
||||
};
|
||||
|
||||
|
||||
|
@ -238,7 +262,7 @@ public:
|
|||
bool init(long sampleRate);
|
||||
|
||||
// Sound Data Feed
|
||||
void write(u16 * finalWave, int length);
|
||||
void write(u16* finalWave, int length);
|
||||
|
||||
// Play Control
|
||||
void pause();
|
||||
|
@ -248,7 +272,7 @@ public:
|
|||
void device_change();
|
||||
|
||||
// Configuration Changes
|
||||
void setThrottle( unsigned short throttle );
|
||||
void setThrottle(unsigned short throttle);
|
||||
|
||||
private:
|
||||
bool failed;
|
||||
|
@ -256,15 +280,15 @@ private:
|
|||
bool playing;
|
||||
UINT32 freq;
|
||||
UINT32 bufferCount;
|
||||
BYTE *buffers;
|
||||
BYTE* buffers;
|
||||
int currentBuffer;
|
||||
int soundBufferLen;
|
||||
|
||||
volatile bool device_changed;
|
||||
|
||||
IXAudio2 *xaud;
|
||||
IXAudio2MasteringVoice *mVoice; // listener
|
||||
IXAudio2SourceVoice *sVoice; // sound source
|
||||
IXAudio2* xaud;
|
||||
IXAudio2MasteringVoice* mVoice; // listener
|
||||
IXAudio2SourceVoice* sVoice; // sound source
|
||||
XAUDIO2_BUFFER buf;
|
||||
XAUDIO2_VOICE_STATE vState;
|
||||
XAudio2_BufferNotify notify; // buffer end notification
|
||||
|
@ -282,20 +306,18 @@ XAudio2_Output::XAudio2_Output()
|
|||
buffers = NULL;
|
||||
currentBuffer = 0;
|
||||
device_changed = false;
|
||||
|
||||
xaud = NULL;
|
||||
mVoice = NULL;
|
||||
sVoice = NULL;
|
||||
ZeroMemory( &buf, sizeof( buf ) );
|
||||
ZeroMemory( &vState, sizeof( vState ) );
|
||||
|
||||
g_notifier.do_register( this );
|
||||
ZeroMemory(&buf, sizeof(buf));
|
||||
ZeroMemory(&vState, sizeof(vState));
|
||||
g_notifier.do_register(this);
|
||||
}
|
||||
|
||||
|
||||
XAudio2_Output::~XAudio2_Output()
|
||||
{
|
||||
g_notifier.do_unregister( this );
|
||||
g_notifier.do_unregister(this);
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -303,26 +325,32 @@ void XAudio2_Output::close()
|
|||
{
|
||||
initialized = false;
|
||||
|
||||
if( sVoice ) {
|
||||
if( playing ) {
|
||||
HRESULT hr = sVoice->Stop( 0 );
|
||||
assert( hr == S_OK );
|
||||
if (sVoice)
|
||||
{
|
||||
if (playing)
|
||||
{
|
||||
HRESULT hr = sVoice->Stop(0);
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
|
||||
sVoice->DestroyVoice();
|
||||
sVoice = NULL;
|
||||
}
|
||||
|
||||
if( buffers ) {
|
||||
free( buffers );
|
||||
if (buffers)
|
||||
{
|
||||
free(buffers);
|
||||
buffers = NULL;
|
||||
}
|
||||
|
||||
if( mVoice ) {
|
||||
if (mVoice)
|
||||
{
|
||||
mVoice->DestroyVoice();
|
||||
mVoice = NULL;
|
||||
}
|
||||
|
||||
if( xaud ) {
|
||||
if (xaud)
|
||||
{
|
||||
xaud->Release();
|
||||
xaud = NULL;
|
||||
}
|
||||
|
@ -336,182 +364,200 @@ void XAudio2_Output::device_change()
|
|||
|
||||
bool XAudio2_Output::init(long sampleRate)
|
||||
{
|
||||
if( failed || initialized ) return false;
|
||||
if (failed || initialized) return false;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
// Initialize XAudio2
|
||||
UINT32 flags = 0;
|
||||
//#ifdef _DEBUG
|
||||
// flags = XAUDIO2_DEBUG_ENGINE;
|
||||
//#endif
|
||||
hr = XAudio2Create(&xaud, flags);
|
||||
|
||||
hr = XAudio2Create( &xaud, flags );
|
||||
if( hr != S_OK ) {
|
||||
wxLogError( _("The XAudio2 interface failed to initialize!") );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("The XAudio2 interface failed to initialize!"));
|
||||
failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
freq = sampleRate;
|
||||
|
||||
// calculate the number of samples per frame first
|
||||
// then multiply it with the size of a sample frame (16 bit * stereo)
|
||||
soundBufferLen = ( freq / 60 ) * 4;
|
||||
|
||||
soundBufferLen = (freq / 60) * 4;
|
||||
// create own buffers to store sound data because it must not be
|
||||
// manipulated while the voice plays from it
|
||||
buffers = (BYTE *)malloc( ( bufferCount + 1 ) * soundBufferLen );
|
||||
buffers = (BYTE*)malloc((bufferCount + 1) * soundBufferLen);
|
||||
// + 1 because we need one temporary buffer when all others are in use
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory( &wfx, sizeof( wfx ) );
|
||||
ZeroMemory(&wfx, sizeof(wfx));
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = freq;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = wfx.nChannels * ( wfx.wBitsPerSample / 8 );
|
||||
wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
|
||||
|
||||
// create sound receiver
|
||||
hr = xaud->CreateMasteringVoice(
|
||||
&mVoice,
|
||||
XAUDIO2_DEFAULT_CHANNELS,
|
||||
XAUDIO2_DEFAULT_SAMPLERATE,
|
||||
0,
|
||||
XA2GetDev(xaud),
|
||||
NULL );
|
||||
if( hr != S_OK ) {
|
||||
wxLogError( _("XAudio2: Creating mastering voice failed!") );
|
||||
&mVoice,
|
||||
XAUDIO2_DEFAULT_CHANNELS,
|
||||
XAUDIO2_DEFAULT_SAMPLERATE,
|
||||
0,
|
||||
XA2GetDev(xaud),
|
||||
NULL);
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("XAudio2: Creating mastering voice failed!"));
|
||||
failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// create sound emitter
|
||||
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, 4.0f, ¬ify );
|
||||
if( hr != S_OK ) {
|
||||
wxLogError( _("XAudio2: Creating source voice failed!") );
|
||||
hr = xaud->CreateSourceVoice(&sVoice, &wfx, 0, 4.0f, ¬ify);
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
wxLogError(_("XAudio2: Creating source voice failed!"));
|
||||
failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if( gopts.upmix ) {
|
||||
if (gopts.upmix)
|
||||
{
|
||||
// set up stereo upmixing
|
||||
XAUDIO2_DEVICE_DETAILS dd;
|
||||
ZeroMemory( &dd, sizeof( dd ) );
|
||||
hr = xaud->GetDeviceDetails( 0, &dd );
|
||||
assert( hr == S_OK );
|
||||
float *matrix = NULL;
|
||||
matrix = (float*)malloc( sizeof( float ) * 2 * dd.OutputFormat.Format.nChannels );
|
||||
if( matrix == NULL ) return false;
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
hr = xaud->GetDeviceDetails(0, &dd);
|
||||
assert(hr == S_OK);
|
||||
float* matrix = NULL;
|
||||
matrix = (float*)malloc(sizeof(float) * 2 * dd.OutputFormat.Format.nChannels);
|
||||
|
||||
if (matrix == NULL) return false;
|
||||
|
||||
bool matrixAvailable = true;
|
||||
switch( dd.OutputFormat.Format.nChannels ) {
|
||||
case 4: // 4.0
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Back L*/ matrix[4] = 1.0000f; matrix[5] = 0.0000f;
|
||||
/*Back R*/ matrix[6] = 0.0000f; matrix[7] = 1.0000f;
|
||||
break;
|
||||
case 5: // 5.0
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*Side L*/ matrix[6] = 1.0000f; matrix[7] = 0.0000f;
|
||||
/*Side R*/ matrix[8] = 0.0000f; matrix[9] = 1.0000f;
|
||||
break;
|
||||
case 6: // 5.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
break;
|
||||
case 7: // 6.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
/*Back C*/ matrix[12] = 0.7071f; matrix[13] = 0.7071f;
|
||||
break;
|
||||
case 8: // 7.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Back L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Back R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
/*Side L*/ matrix[12] = 1.0000f; matrix[13] = 0.0000f;
|
||||
/*Side R*/ matrix[14] = 0.0000f; matrix[15] = 1.0000f;
|
||||
break;
|
||||
default:
|
||||
matrixAvailable = false;
|
||||
break;
|
||||
|
||||
switch (dd.OutputFormat.Format.nChannels)
|
||||
{
|
||||
case 4: // 4.0
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Back L*/ matrix[4] = 1.0000f; matrix[5] = 0.0000f;
|
||||
/*Back R*/ matrix[6] = 0.0000f; matrix[7] = 1.0000f;
|
||||
break;
|
||||
|
||||
case 5: // 5.0
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*Side L*/ matrix[6] = 1.0000f; matrix[7] = 0.0000f;
|
||||
/*Side R*/ matrix[8] = 0.0000f; matrix[9] = 1.0000f;
|
||||
break;
|
||||
|
||||
case 6: // 5.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
break;
|
||||
|
||||
case 7: // 6.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
/*Back C*/ matrix[12] = 0.7071f; matrix[13] = 0.7071f;
|
||||
break;
|
||||
|
||||
case 8: // 7.1
|
||||
//Speaker \ Left Source Right Source
|
||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||
/*Back L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||
/*Back R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||
/*Side L*/ matrix[12] = 1.0000f; matrix[13] = 0.0000f;
|
||||
/*Side R*/ matrix[14] = 0.0000f; matrix[15] = 1.0000f;
|
||||
break;
|
||||
|
||||
default:
|
||||
matrixAvailable = false;
|
||||
break;
|
||||
}
|
||||
if( matrixAvailable ) {
|
||||
hr = sVoice->SetOutputMatrix( NULL, 2, dd.OutputFormat.Format.nChannels, matrix );
|
||||
assert( hr == S_OK );
|
||||
|
||||
if (matrixAvailable)
|
||||
{
|
||||
hr = sVoice->SetOutputMatrix(NULL, 2, dd.OutputFormat.Format.nChannels, matrix);
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
free( matrix );
|
||||
|
||||
free(matrix);
|
||||
matrix = NULL;
|
||||
}
|
||||
|
||||
|
||||
hr = sVoice->Start( 0 );
|
||||
assert( hr == S_OK );
|
||||
hr = sVoice->Start(0);
|
||||
assert(hr == S_OK);
|
||||
playing = true;
|
||||
|
||||
currentBuffer = 0;
|
||||
device_changed = false;
|
||||
|
||||
initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void XAudio2_Output::write(u16 * finalWave, int length)
|
||||
void XAudio2_Output::write(u16* finalWave, int length)
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
if (!initialized || failed) return;
|
||||
|
||||
while( true ) {
|
||||
if ( device_changed ) {
|
||||
while (true)
|
||||
{
|
||||
if (device_changed)
|
||||
{
|
||||
close();
|
||||
|
||||
if (!init(freq)) return;
|
||||
}
|
||||
|
||||
sVoice->GetState( &vState );
|
||||
sVoice->GetState(&vState);
|
||||
assert(vState.BuffersQueued <= bufferCount);
|
||||
|
||||
assert( vState.BuffersQueued <= bufferCount );
|
||||
|
||||
if( vState.BuffersQueued < bufferCount ) {
|
||||
if( vState.BuffersQueued == 0 ) {
|
||||
if (vState.BuffersQueued < bufferCount)
|
||||
{
|
||||
if (vState.BuffersQueued == 0)
|
||||
{
|
||||
// buffers ran dry
|
||||
if( systemVerbose & VERBOSE_SOUNDOUTPUT ) {
|
||||
if (systemVerbose & VERBOSE_SOUNDOUTPUT)
|
||||
{
|
||||
static unsigned int i = 0;
|
||||
log( "XAudio2: Buffers were not refilled fast enough (i=%i)\n", i++ );
|
||||
log("XAudio2: Buffers were not refilled fast enough (i=%i)\n", i++);
|
||||
}
|
||||
}
|
||||
|
||||
// there is at least one free buffer
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// the maximum number of buffers is currently queued
|
||||
if( !speedup && throttle && !gba_joybus_active ) {
|
||||
if (!speedup && throttle && !gba_joybus_active)
|
||||
{
|
||||
// wait for one buffer to finish playing
|
||||
if (WaitForSingleObject( notify.hBufferEndEvent, 10000 ) == WAIT_TIMEOUT) {
|
||||
if (WaitForSingleObject(notify.hBufferEndEvent, 10000) == WAIT_TIMEOUT)
|
||||
{
|
||||
device_changed = true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// drop current audio frame
|
||||
return;
|
||||
}
|
||||
|
@ -519,26 +565,24 @@ void XAudio2_Output::write(u16 * finalWave, int length)
|
|||
}
|
||||
|
||||
// copy & protect the audio data in own memory area while playing it
|
||||
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], finalWave, soundBufferLen );
|
||||
|
||||
CopyMemory(&buffers[ currentBuffer * soundBufferLen ], finalWave, soundBufferLen);
|
||||
buf.AudioBytes = soundBufferLen;
|
||||
buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ];
|
||||
|
||||
currentBuffer++;
|
||||
currentBuffer %= ( bufferCount + 1 ); // + 1 because we need one temporary buffer
|
||||
|
||||
HRESULT hr = sVoice->SubmitSourceBuffer( &buf ); // send buffer to queue
|
||||
assert( hr == S_OK );
|
||||
currentBuffer %= (bufferCount + 1); // + 1 because we need one temporary buffer
|
||||
HRESULT hr = sVoice->SubmitSourceBuffer(&buf); // send buffer to queue
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
|
||||
|
||||
void XAudio2_Output::pause()
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
if (!initialized || failed) return;
|
||||
|
||||
if( playing ) {
|
||||
HRESULT hr = sVoice->Stop( 0 );
|
||||
assert( hr == S_OK );
|
||||
if (playing)
|
||||
{
|
||||
HRESULT hr = sVoice->Stop(0);
|
||||
assert(hr == S_OK);
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
|
@ -546,11 +590,12 @@ void XAudio2_Output::pause()
|
|||
|
||||
void XAudio2_Output::resume()
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
if (!initialized || failed) return;
|
||||
|
||||
if( !playing ) {
|
||||
HRESULT hr = sVoice->Start( 0 );
|
||||
assert( hr == S_OK );
|
||||
if (!playing)
|
||||
{
|
||||
HRESULT hr = sVoice->Start(0);
|
||||
assert(hr == S_OK);
|
||||
playing = true;
|
||||
}
|
||||
}
|
||||
|
@ -558,34 +603,36 @@ void XAudio2_Output::resume()
|
|||
|
||||
void XAudio2_Output::reset()
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
if (!initialized || failed) return;
|
||||
|
||||
if( playing ) {
|
||||
HRESULT hr = sVoice->Stop( 0 );
|
||||
assert( hr == S_OK );
|
||||
if (playing)
|
||||
{
|
||||
HRESULT hr = sVoice->Stop(0);
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
|
||||
sVoice->FlushSourceBuffers();
|
||||
sVoice->Start( 0 );
|
||||
sVoice->Start(0);
|
||||
playing = true;
|
||||
}
|
||||
|
||||
|
||||
void XAudio2_Output::setThrottle( unsigned short throttle )
|
||||
void XAudio2_Output::setThrottle(unsigned short throttle)
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
if (!initialized || failed) return;
|
||||
|
||||
if( throttle == 0 ) throttle = 100;
|
||||
HRESULT hr = sVoice->SetFrequencyRatio( (float)throttle / 100.0f );
|
||||
assert( hr == S_OK );
|
||||
if (throttle == 0) throttle = 100;
|
||||
|
||||
HRESULT hr = sVoice->SetFrequencyRatio((float)throttle / 100.0f);
|
||||
assert(hr == S_OK);
|
||||
}
|
||||
|
||||
void xaudio2_device_changed( XAudio2_Output * instance )
|
||||
void xaudio2_device_changed(XAudio2_Output* instance)
|
||||
{
|
||||
instance->device_change();
|
||||
}
|
||||
|
||||
SoundDriver *newXAudio2_Output()
|
||||
SoundDriver* newXAudio2_Output()
|
||||
{
|
||||
return new XAudio2_Output();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue