#include "SNDinc.h"

#include <windows.h>
#include <mmsystem.h>

#include "sndtest.h"

//---test WinMM-driver capabilities
#ifdef __WATCOMC__

#define CPUID                           "db 0x0F"\
                                        "db 0x0a2"\

void IsPentiumOrMMX(BOOL *bIsPentiumOrBetter, BOOL *IsMMX);
#pragma aux IsPentiumOrMMX=\
                  "pushfd"\
                  "pop     eax"\
                  "mov     ebx,eax"\
                  "xor     eax,00200000h"\
                  "push    eax"\
                  "popfd"\
                  "pushfd"\
                  "pop     eax"\
                  "push    ebx"\
                  "popfd"\
                  "and     eax,00200000h"\
                  "and     ebx,00200000h"\
                  "cmp     eax,ebx"\
                  "jne     IsPent"\
                  "mov     dword ptr [esi],00h "\
                  "mov     dword ptr [edi],00h"\
                  "jmp     Done"\      
                  "IsPent :"\
                  "mov       dword ptr [esi],01h "\               
                  "mov       eax,01h"\
                  CPUID\
                  "test      edx,00800000h"\
                  "jnz       IsMmx"\                
                  "mov       dword ptr [edi],00h"\
                  "jmp       Done"\             
                  "IsMmx:"\
                  "mov       dword ptr [edi],01h"\
                  "Done:"\
                parm [esi] [edi]\
                modify [ebx eax edx] 

#else
#define CPUID                           __asm _emit 0x0F __asm _emit 0x0a2
void IsPentiumOrMMX(BOOL *bIsPentiumOrBetter, BOOL *IsMMX)
{
    __asm{ 
        pushfd
        mov     esi,bIsPentiumOrBetter
        mov     edi,IsMMX
        pop     eax
        mov     ebx,eax
        xor     eax,00200000h
        push    eax
        popfd
        pushfd
        pop     eax
        push    ebx
        popfd
        and     eax,00200000h
        and     ebx,00200000h
        cmp     eax,ebx
        jne     IsPent

        mov     dword ptr [esi],00h 
        mov     dword ptr [edi],00h
        jmp     Done

    IsPent: 
        mov     dword ptr [esi],01h 
        
        mov     eax,01h
        CPUID
        test    edx,00800000h
        jnz     IsMmx
    
        mov     dword ptr [edi],00h
        jmp     Done
   
    IsMmx:  
        mov     dword ptr [edi],01h

    Done:
    }
}
#endif

BOOL SND_CALL SND_fn_bTestSnd_Pentium(void)
{
    BOOL bMMX,bP5;

    IsPentiumOrMMX(&bP5,&bMMX);

    return bP5;
}

BOOL SND_CALL SND_fn_bTestSnd_MMX(void)
{
    BOOL bMMX,bP5;

    IsPentiumOrMMX(&bP5,&bMMX);

    return (bP5 && bMMX);
}

BOOL SND_CALL SND_fn_bTestSnd_WinMM(WAVEFORMATEX *format)
{
        MMRESULT res;
        WAVEOUTCAPS DevCaps;
        long winmm_const[12]={WAVE_FORMAT_1M08,WAVE_FORMAT_1S08
            ,WAVE_FORMAT_1M16,WAVE_FORMAT_1S16
            ,WAVE_FORMAT_2M08,WAVE_FORMAT_2S08
            ,WAVE_FORMAT_2M16,WAVE_FORMAT_2S16
            ,WAVE_FORMAT_4M08,WAVE_FORMAT_4S08
            ,WAVE_FORMAT_4M16,WAVE_FORMAT_4S16};
        long id_winmm_const;

        if ((res=waveOutGetDevCaps(WAVE_MAPPER,&DevCaps,sizeof(DevCaps)))==MMSYSERR_NOERROR)
        {
            id_winmm_const=(format->nChannels-1)
				+(2*(format->wBitsPerSample/8-1))
				+((format->nSamplesPerSec<=11025)?0:((format->nSamplesPerSec<=22050)?4:8));

            if (DevCaps.dwFormats & winmm_const[id_winmm_const])
                return TRUE;
        }
        return FALSE;
}

BOOL SND_CALL SND_fn_bTestSnd_Win32(void)
{
	OSVERSIONINFO ver;
	
	memset(&ver,0,sizeof(OSVERSIONINFO));
	ver.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
	GetVersionEx(&ver);

	if (ver.dwPlatformId==VER_PLATFORM_WIN32s)
		return FALSE;

	return TRUE;
}

BOOL SND_CALL SND_fn_bTestSnd_WinNT(void)
{
	OSVERSIONINFO ver;
	
	memset(&ver,0,sizeof(OSVERSIONINFO));
	ver.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
	GetVersionEx(&ver);

	if (ver.dwPlatformId==VER_PLATFORM_WIN32_NT)
		return TRUE;

	return FALSE;
}
