diff --git a/tools/vio2sf/src/vio2sf/desmume/SPU.cpp b/tools/vio2sf/src/vio2sf/desmume/SPU.cpp index 5a4ccd767..eea2f48db 100644 --- a/tools/vio2sf/src/vio2sf/desmume/SPU.cpp +++ b/tools/vio2sf/src/vio2sf/desmume/SPU.cpp @@ -48,9 +48,6 @@ #include "NDSSystem.h" #include "matrix.h" - - - //===================CONFIGURATION======================== #include "src/xsfc/drvimpl.h" extern "C" unsigned long dwInterpolation; @@ -205,6 +202,7 @@ extern "C" void SPU_Reset(void) static long tot_samples; static long update_trunc; + extern "C" int SPU_Init(int coreid, int buffersize) { int i, j; @@ -546,16 +544,18 @@ static FORCEINLINE s32 Interpolate(SPUInterpolationMode INTERPOLATE_MODE, s32 a, typedef void (*TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT)(unsigned long addr, int type); typedef BOOL (*TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED)(unsigned long addr); typedef unsigned long (*TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME)(unsigned long addr); +typedef BOOL (*TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE)(); double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); } -extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT addInstrument; -extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED isInstrumentMuted; -extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME getInstrumentVolume; +extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT addInstrument; +extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED isInstrumentMuted; +extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME getInstrumentVolume; +extern "C" TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE isInstrumentSelectionActive; -static FORCEINLINE void Fetch8BitData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct *chan, s32 *data, bool INSTRUMENT_EDIT) +static FORCEINLINE void Fetch8BitData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct *chan, s32 *data) { u32 loc = sputrunc(chan->sampcnt); if(INTERPOLATE_MODE != SPUInterpolation_None) @@ -570,8 +570,7 @@ static FORCEINLINE void Fetch8BitData(SPUInterpolationMode INTERPOLATE_MODE, cha else *data = (s32)chan->buf8[loc] << 8; - //if (addInstrument && isInstrumentMuted && getInstrumentVolume) - if(INSTRUMENT_EDIT) + if (isInstrumentSelectionActive && isInstrumentSelectionActive() && addInstrument && isInstrumentMuted && getInstrumentVolume) { addInstrument(chan->addr, 0); if (isInstrumentMuted(chan->addr)) *data = 0; @@ -579,7 +578,7 @@ static FORCEINLINE void Fetch8BitData(SPUInterpolationMode INTERPOLATE_MODE, cha } } -static FORCEINLINE void Fetch16BitData(SPUInterpolationMode INTERPOLATE_MODE, const channel_struct * const chan, s32 *data, bool INSTRUMENT_EDIT) +static FORCEINLINE void Fetch16BitData(SPUInterpolationMode INTERPOLATE_MODE, const channel_struct * const chan, s32 *data) { const s16* const buf16 = chan->buf16; const int shift = 1; @@ -597,8 +596,7 @@ static FORCEINLINE void Fetch16BitData(SPUInterpolationMode INTERPOLATE_MODE, co else *data = (s32)buf16[sputrunc(chan->sampcnt)]; - if(INSTRUMENT_EDIT) - //if (addInstrument && isInstrumentMuted && getInstrumentVolume) + if (isInstrumentSelectionActive && isInstrumentSelectionActive() && addInstrument && isInstrumentMuted && getInstrumentVolume) { addInstrument(chan->addr, 1); if (isInstrumentMuted(chan->addr)) *data = 0; @@ -606,7 +604,7 @@ static FORCEINLINE void Fetch16BitData(SPUInterpolationMode INTERPOLATE_MODE, co } } -static FORCEINLINE void FetchADPCMData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct * const chan, s32 * const data, bool INSTRUMENT_EDIT) +static FORCEINLINE void FetchADPCMData(SPUInterpolationMode INTERPOLATE_MODE, channel_struct * const chan, s32 * const data) { // No sense decoding, just return the last sample if (chan->lastsampcnt != sputrunc(chan->sampcnt)){ @@ -638,8 +636,7 @@ static FORCEINLINE void FetchADPCMData(SPUInterpolationMode INTERPOLATE_MODE, ch else *data = (s32)chan->pcm16b; - if(INSTRUMENT_EDIT) - //if (addInstrument && isInstrumentMuted && getInstrumentVolume) + if (isInstrumentSelectionActive && isInstrumentSelectionActive() && addInstrument && isInstrumentMuted && getInstrumentVolume) { addInstrument(chan->addr, 2); if (isInstrumentMuted(chan->addr)) *data = 0; @@ -647,7 +644,7 @@ static FORCEINLINE void FetchADPCMData(SPUInterpolationMode INTERPOLATE_MODE, ch } } -static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data, bool INSTRUMENT_EDIT) +static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data) { if(chan->num < 8) { @@ -685,8 +682,7 @@ static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data, bool INSTR *data = (s32)chan->psgnoise_last; } - if(INSTRUMENT_EDIT) - //if (addInstrument && isInstrumentMuted && getInstrumentVolume) + if (isInstrumentSelectionActive && isInstrumentSelectionActive() && addInstrument && isInstrumentMuted && getInstrumentVolume) { addInstrument(0, 3); if (isInstrumentMuted(0)) *data = 0; @@ -789,7 +785,7 @@ FORCEINLINE static void SPU_Mix(int CHANNELS, SPU_struct* SPU, channel_struct *c } } -FORCEINLINE static void ____SPU_ChanUpdate(int CHANNELS, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, SPU_struct* const SPU, channel_struct* const chan, bool INSTRUMENT_EDIT) +FORCEINLINE static void ____SPU_ChanUpdate(int CHANNELS, int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, SPU_struct* const SPU, channel_struct* const chan) { for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) { @@ -798,10 +794,10 @@ FORCEINLINE static void ____SPU_ChanUpdate(int CHANNELS, int FORMAT, SPUInterpol s32 data; switch(FORMAT) { - case 0: Fetch8BitData(INTERPOLATE_MODE, chan, &data, INSTRUMENT_EDIT); break; - case 1: Fetch16BitData(INTERPOLATE_MODE, chan, &data, INSTRUMENT_EDIT); break; - case 2: FetchADPCMData(INTERPOLATE_MODE, chan, &data, INSTRUMENT_EDIT); break; - case 3: FetchPSGData(chan, &data, INSTRUMENT_EDIT); break; + case 0: Fetch8BitData(INTERPOLATE_MODE, chan, &data); break; + case 1: Fetch16BitData(INTERPOLATE_MODE, chan, &data); break; + case 2: FetchADPCMData(INTERPOLATE_MODE, chan, &data); break; + case 3: FetchPSGData(chan, &data); break; } SPU_Mix(CHANNELS, SPU, chan, data); } @@ -814,26 +810,26 @@ FORCEINLINE static void ____SPU_ChanUpdate(int CHANNELS, int FORMAT, SPUInterpol } } -FORCEINLINE static void ___SPU_ChanUpdate(int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan, bool INSTRUMENT_EDIT) +FORCEINLINE static void ___SPU_ChanUpdate(int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) { if(!actuallyMix) - ____SPU_ChanUpdate(-1,FORMAT,INTERPOLATE_MODE,SPU,chan,INSTRUMENT_EDIT); + ____SPU_ChanUpdate(-1,FORMAT,INTERPOLATE_MODE,SPU,chan); else if (chan->pan == 0) - ____SPU_ChanUpdate(0,FORMAT,INTERPOLATE_MODE,SPU,chan,INSTRUMENT_EDIT); + ____SPU_ChanUpdate(0,FORMAT,INTERPOLATE_MODE,SPU,chan); else if (chan->pan == 127) - ____SPU_ChanUpdate(2,FORMAT,INTERPOLATE_MODE,SPU,chan,INSTRUMENT_EDIT); + ____SPU_ChanUpdate(2,FORMAT,INTERPOLATE_MODE,SPU,chan); else - ____SPU_ChanUpdate(1,FORMAT,INTERPOLATE_MODE,SPU,chan,INSTRUMENT_EDIT); + ____SPU_ChanUpdate(1,FORMAT,INTERPOLATE_MODE,SPU,chan); } -FORCEINLINE static void __SPU_ChanUpdate(SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan, bool INSTRUMENT_EDIT) +FORCEINLINE static void __SPU_ChanUpdate(SPUInterpolationMode INTERPOLATE_MODE, const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) { - ___SPU_ChanUpdate(chan->format,INTERPOLATE_MODE,actuallyMix, SPU, chan, INSTRUMENT_EDIT); + ___SPU_ChanUpdate(chan->format,INTERPOLATE_MODE,actuallyMix, SPU, chan); } -FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan, bool INSTRUMENT_EDIT) +FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) { - __SPU_ChanUpdate(spuInterpolationMode(),actuallyMix, SPU, chan,INSTRUMENT_EDIT); + __SPU_ChanUpdate(spuInterpolationMode(),actuallyMix, SPU, chan); } @@ -870,9 +866,7 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length) SPU->buflength = length; // Mix audio - if (addInstrument && isInstrumentMuted && getInstrumentVolume) - _SPU_ChanUpdate(!isChannelMuted(i) && actuallyMix, SPU, chan, true); - else _SPU_ChanUpdate(!isChannelMuted(i) && actuallyMix, SPU, chan, false); + _SPU_ChanUpdate(!isChannelMuted(i) && actuallyMix, SPU, chan); } // convert from 32-bit->16-bit diff --git a/tools/vio2sf/src/vio2sf/desmume/soundView.cpp b/tools/vio2sf/src/vio2sf/desmume/soundView.cpp index 404d13a6c..2f1847310 100644 --- a/tools/vio2sf/src/vio2sf/desmume/soundView.cpp +++ b/tools/vio2sf/src/vio2sf/desmume/soundView.cpp @@ -104,6 +104,12 @@ extern "C" int SoundView_DlgOpen(HINSTANCE hAppInst) { HWND hDlg; + if(SoundView_Data != NULL) + { + SetWindowPos(SoundView_Data->hDlg,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE); + return 0; + } + SoundView_Data = new SoundView_DataStruct(); if(SoundView_Data == NULL) return 0; diff --git a/tools/vio2sf/src/xsfc/in_xsf.cpp b/tools/vio2sf/src/xsfc/in_xsf.cpp index 18d607ea4..b62923b04 100644 --- a/tools/vio2sf/src/xsfc/in_xsf.cpp +++ b/tools/vio2sf/src/xsfc/in_xsf.cpp @@ -268,10 +268,12 @@ public: return false; } - lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT, addInstrument); - lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED, isInstrumentMuted); - lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME, getInstrumentVolume); + lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT, addInstrument); + lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED, isInstrumentMuted); + lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME, getInstrumentVolume); + lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE, isInstrumentSelectionActive); lpif->SetExtendParamImmediate(EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW, openSoundView); + return true; } @@ -1024,7 +1026,7 @@ protected: int request2 = ::InterlockedExchange((LPLONG)&m_lRequest, 0); if (request2 & (1 << REQUEST_STOP)) { - request1 |= (1 << REQUEST_STOP); + request1 |= (1 << REQUEST_STOP); break; } } @@ -1123,7 +1125,7 @@ protected: { xsfdrv.seek_kil = 1; Request(REQUEST_STOP); - + MSG msg; while( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) ) if( GetMessage( &msg, 0, 0, 0)>0 ) { @@ -1131,6 +1133,7 @@ protected: DispatchMessage(&msg); } + } while (::WaitForSingleObject(m_hThread, 20) == WAIT_TIMEOUT); ::CloseHandle(m_hThread); m_hThread = NULL; diff --git a/tools/vio2sf/src/xsfc/in_xsfcfg.cpp b/tools/vio2sf/src/xsfc/in_xsfcfg.cpp index e88273392..3c51a24f1 100644 --- a/tools/vio2sf/src/xsfc/in_xsfcfg.cpp +++ b/tools/vio2sf/src/xsfc/in_xsfcfg.cpp @@ -189,6 +189,11 @@ unsigned long GetDlgItemHex(HWND wnd, UINT wndMsg) HWND dlgInstrumentSelection=0; HWND dlgMixerInstrument[50]; +BOOL isInstrumentSelectionActive() +{ + return (dlgInstrumentSelection != 0); +} + class Instrument { public: @@ -558,6 +563,7 @@ BOOL CALLBACK dlgProcInstrumentSelection(HWND dlg, UINT message, WPARAM wParam, } return FALSE; } + static BOOL CALLBACK DialogProcPref(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static bool initialized = false; @@ -567,7 +573,7 @@ static BOOL CALLBACK DialogProcPref(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_BUTTON_VIEWSPU: - if(soundViewCallbacks.doOpenSoundView) soundViewCallbacks.doOpenSoundView(hDLL); + if(soundViewCallbacks.doOpenSoundView) soundViewCallbacks.doOpenSoundView(hDLL); break; case IDC_BUTTON_INSTRUMENTSELECTION: @@ -587,6 +593,7 @@ static BOOL CALLBACK DialogProcPref(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR } } break; + case IDC_COMBO_INTERPOLATION: if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) { diff --git a/tools/vio2sf/src/xsfc/in_xsfcfg.h b/tools/vio2sf/src/xsfc/in_xsfcfg.h index 93774489a..1ca08a3bc 100644 --- a/tools/vio2sf/src/xsfc/in_xsfcfg.h +++ b/tools/vio2sf/src/xsfc/in_xsfcfg.h @@ -14,9 +14,9 @@ void winamp_config_dialog(HWND hwndWinamp, HWND hwndParent); void addInstrument(unsigned long addr, int type); BOOL isInstrumentMuted(unsigned long addr); unsigned long getInstrumentVolume(unsigned long addr); +BOOL isInstrumentSelectionActive(); void openSoundView(void* callback); - #ifdef __cplusplus } #endif diff --git a/tools/vio2sf/src/xsfc/xsfdrv.c b/tools/vio2sf/src/xsfc/xsfdrv.c index 4c54125e3..98525071e 100644 --- a/tools/vio2sf/src/xsfc/xsfdrv.c +++ b/tools/vio2sf/src/xsfc/xsfdrv.c @@ -57,11 +57,13 @@ static void PASCAL XSFSetExtendParam(DWORD dwId, LPCWSTR lpPtr) } #endif -TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT addInstrument=0; -TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED isInstrumentMuted=0; -TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME getInstrumentVolume=0; +TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT addInstrument=0; +TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED isInstrumentMuted=0; +TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME getInstrumentVolume=0; +TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE isInstrumentSelectionActive=0; TYPE_EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW openSoundView=0; + int SoundView_DlgOpen(HINSTANCE hAppIndst); void SoundView_DlgClose(); @@ -84,7 +86,6 @@ typedef struct CallbackSet struct CallbackSet soundViewCallbacks = { &doOpenSoundView, &killSoundView }; - static void PASCAL XSFSetExtendParamImmediate(DWORD dwId, LPVOID lpPtr) { switch(dwId) @@ -93,12 +94,14 @@ static void PASCAL XSFSetExtendParamImmediate(DWORD dwId, LPVOID lpPtr) dwInterpolation = *(unsigned long*)lpPtr; break; - case EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT: addInstrument = (TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT) lpPtr; break; - case EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED: isInstrumentMuted = (TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED) lpPtr; break; - case EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME: getInstrumentVolume = (TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME) lpPtr; break; - case EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW: openSoundView = (TYPE_EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW) lpPtr; + case EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT: addInstrument = (TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT) lpPtr; break; + case EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED: isInstrumentMuted = (TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED) lpPtr; break; + case EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME: getInstrumentVolume = (TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME) lpPtr; break; + case EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE: isInstrumentSelectionActive = (TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE) lpPtr; break; + case EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW: + openSoundView = (TYPE_EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW) lpPtr; openSoundView(&soundViewCallbacks); - break; + break; } } diff --git a/tools/vio2sf/src/xsfc/xsfdrv.h b/tools/vio2sf/src/xsfc/xsfdrv.h index 95b807f8a..d0f0c02f6 100644 --- a/tools/vio2sf/src/xsfc/xsfdrv.h +++ b/tools/vio2sf/src/xsfc/xsfdrv.h @@ -28,14 +28,16 @@ typedef struct #define EXTEND_PARAM_IMMEDIATE_INTERPOLATION_LINEAR 1 #define EXTEND_PARAM_IMMEDIATE_INTERPOLATION_COSINE 2 -#define EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT 1 -#define EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED 2 -#define EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME 3 -#define EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW 4 +#define EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT 1 +#define EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED 2 +#define EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME 3 +#define EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE 4 +#define EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW 5 typedef void (*TYPE_EXTEND_PARAM_IMMEDIATE_ADDINSTRUMENT)(unsigned long addr, int type); typedef BOOL (*TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTMUTED)(unsigned long addr); typedef unsigned long (*TYPE_EXTEND_PARAM_IMMEDIATE_GETINSTRUMENTVOLUME)(unsigned long addr); +typedef BOOL (*TYPE_EXTEND_PARAM_IMMEDIATE_ISINSTRUMENTSELECTIONACTIVE)(); typedef unsigned long (*TYPE_EXTEND_PARAM_IMMEDIATE_OPENSOUNDVIEW)(void* callback); typedef IXSFDRV * (PASCAL * LPFNXSFDRVSETUP)(LPFNGETLIB_XSFDRV lpfn, void *lpWork); diff --git a/tools/vio2sf/src/xsfc/xsfui.rc b/tools/vio2sf/src/xsfc/xsfui.rc index 6ec6114f9..09ac23243 100644 --- a/tools/vio2sf/src/xsfc/xsfui.rc +++ b/tools/vio2sf/src/xsfc/xsfui.rc @@ -91,7 +91,7 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,129,181,35,15,NOT WS_VISIBLE COMBOBOX IDC_COMBO_INTERPOLATION,10,156,78,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Instruments",IDC_BUTTON_INSTRUMENTSELECTION,70,12,50,14 - PUSHBUTTON "View SPU",IDC_BUTTON_VIEWSPU,125,12,37,14 + PUSHBUTTON "View SPU",IDC_BUTTON_VIEWSPU,123,12,37,14 END