⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsapi.cpp

📁 赤壁之战的游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                {
                /* Zero out the rest of this block */
                if( lpwiWave->pwfx->wBitsPerSample == 8 )
                    memset( lpWrite2+uChkErr, 128, ((UINT)dwLen2-uChkErr));
                else if( lpwiWave->pwfx->wBitsPerSample == 16 )
                    memset( lpWrite2+uChkErr, 0, ((UINT)dwLen2-uChkErr));
                /* Enable play completion detection code at the beginning
                 * of the next call
                 */
                lpwiWave->bFoundEnd = TRUE;
                if( dwPlay > lpwiWave->dwNextWriteOffset )
                    lpwiWave->nRemainingSegments = (lpwiWave->dwNextWriteOffset
                                                + lpwiWave->dwBufferSize - dwPlay)
                                                / lpwiWave->dwBufferSegSize;
                else
                    lpwiWave->nRemainingSegments = (lpwiWave->dwNextWriteOffset
                                                - dwPlay)
                                                / lpwiWave->dwBufferSegSize;
                }
            else
                {
                lpTemp = lpWrite2;
                do
                    {
                    /* Continue decrementing our count and moving our temp
                     * pointer forward until we've read the file enough times
                     * to fill the buffer.  NOTE: It's probably not efficient
                     * to bother with the overhead of streaming a file that's
                     * not at least as large as the buffer... */
                    lpTemp += uChkErr;
                    dwLen2 -= uChkErr;
                    nChkErr = WaveStartDataRead( &lpwiWave->hmmio,
                                                    &lpwiWave->mmck,
                                                    &lpwiWave->mmckInRIFF );
                    nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen2,
                                            lpTemp,
                                            &lpwiWave->mmck, &uChkErr );
                    } while( uChkErr < dwLen2 );
                }
            }
        }
    else if( dwLen2 && lpwiWave->bDonePlaying )
        {
        // Set the appropriate silence value
        memset( lpWrite2,
                    lpwiWave->pwfx->wBitsPerSample == 8 ? 128 : 0,
                    dwLen2 );
        }

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif

    lpwiWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
                                      (LPVOID)lpWrite2, dwLen2 );

#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif

    lpwiWave->dwNextWriteOffset += lpwiWave->dwBufferSegSize;
    if( lpwiWave->dwNextWriteOffset >= lpwiWave->dwBufferSize )
        lpwiWave->dwNextWriteOffset -= lpwiWave->dwBufferSize;


#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif

	//OutputString( DS_nVolume, "\n" );
	// set volume
    if( lpwiWave->lpDSBStreamBuffer->SetVolume( DS_nVolume ) != DS_OK )
	{
		OutputDebugString( "DS dynamic error: set volume!\n" );
		//-----debug
#ifdef	_DS_LOG_
		FILE*fp=fopen( "DSTest.log","at" );
		fprintf(fp,"E" );
		fclose(fp);
#endif
		//-----debug
		goto END_TIME;
	}

	// set pan
    if( lpwiWave->lpDSBStreamBuffer->SetPan( DS_nPan ) != DS_OK )
	{
		OutputDebugString( "DS dynamic error: set pan!\n" );
		//-----debug
#ifdef	_DS_LOG_
		FILE*fp=fopen( "DSTest.log","at" );
		fprintf(fp,"F" );
		fclose(fp);
#endif
		//-----debug
		goto END_TIME;
	}

	// fade in or fade out
	if( DS_nFadeMode == DS_FADE_OUT )
	{
		if( lpwiWave->FadeOut() )	
			DS_nFadeMode = DS_FADE_NONE;	// end fade session
	}
	if( DS_nFadeMode == DS_FADE_IN  )
	{
		if( lpwiWave->FadeIn() ) 
			DS_nFadeMode = DS_FADE_NONE;	// end fade session
	}

END_TIME:

    bInTimer = FALSE;
	ReleaseMutex( hMutex );
}
//////////////////



//==========================================================================
//
// class WAVESTATIC
//
//==========================================================================
//////////////////
// used by class WAVESTATIC
// load sound buffer
// nIndex		:	ID in global wave array
// return value	:	0 if succeeded, otherwise error number,
int StreamBufferSetupS( int nIndex );

// release sound buffer
// nIndex	:	ID in global wave array
void StreamBufferReleaseS( int nIndex );

// set lpswWave by index in lpwsWaves
// nIndex	:	ID in global wave array
LPWAVESTATIC SetToGlobalS( int nIndex );

// constructor
WAVESTATIC::CStaticWave()
{
	nID = WAVE_OBJECT_NONE;							/* ID, if not equals to WAVE_OBJECT_NONE,
											the wave file is opened */
	//strFileName[65];				/* wave file name */
    bLoopFile = FALSE;				/* Should we loop playback? */
	bPlaying = FALSE;				/* if wave file is playing */
    lpDSBStreamBuffer = NULL;		/* Points to DirectSoundBuffer */
	cbSize = 0;
	pbData = NULL;
}

// destructor
WAVESTATIC::~CStaticWave()
{
	if( nID != WAVE_OBJECT_NONE )
	{
        PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
		Stop();
		OutputDebugString( "DS Warning: not stop playing sound before destroy sound buffer!\n" );
	}
}

// load sound buffer
// filename		:	wave file name
// return value	:	TRUE if succeeded
BOOL WAVESTATIC::Load( LPCTSTR filename )
{
	// register this sound buffer to global array
	BOOL bSuccess = FALSE;
	for( int i=0; i< WAVE_OBJECT_MAXS; i++ )
	{
		if( lpwsWaves[i] == NULL )
		{
			lpwsWaves[i] = this;
			nID = i;
			bSuccess = TRUE;
#ifdef	__TEST_SOUND__
			for( int x=0; x<WAVE_OBJECT_MAXS; x++ )
			{
				if( nID == x )	continue;
				if( !lpwsWaves[x] ) continue;
				ASSERT( this != lpwsWaves[x] );
			}
#endif
			break;
		}
	}
	if( !bSuccess )
	{
		return FALSE;
	}
	
	// load sound with a wave format file
	strcpy( strFileName, filename );
	if(StreamBufferSetupS( nID ) != 0 )
	{
		// Error opening the WAVE file so abort
		lpwsWaves[nID] = NULL;
		nID = WAVE_OBJECT_NONE;
		return FALSE;
	}
	nSWaveCounter++;
#ifdef	__TEST_SOUND__
	ASSERT( lpwsWaves[nID]->lpDSBStreamBuffer );
#endif

#ifdef	_DEBUG
	char	tmp[33];
	itoa( nSWaveCounter, tmp, 10 );
//	OutputDebugString( "DS Static wave Load:" );
//	OutputDebugString(tmp);
//	OutputDebugString("\n");
#endif

	return TRUE;
}

// release sound buffer
void WAVESTATIC::Close()
{
	if( nID == WAVE_OBJECT_NONE )	return;

//	WaitForSingleObject( hMutex, INFINITE );
	// release sound buffer, and unregister from global array
	StreamBufferReleaseS( nID );
	lpwsWaves[nID] = NULL;
	nID = WAVE_OBJECT_NONE;
	nSWaveCounter--;

#ifdef	_DEBUG
	char	tmp[33];
	itoa( nSWaveCounter, tmp, 10 );
//	ReleaseMutex( hMutex );
//	OutputDebugString( "DS Static wave Close:" );
//	OutputDebugString(tmp);
//	OutputDebugString("\n");
#endif
}

// dwFlags		:	TRUE if looping
// pos			:	position to play from
// return value	:	TRUE if played
// if this object is playing, stop and playing again
BOOL WAVESTATIC::Play( DWORD dwFlags/*=DSBPLAY_LOOPING*/, DWORD pos/*=0*/ )
{
	if( !DS_bSoundEnable )	return TRUE;

	// release stoped wave files previously played
	DS_CloseStopedSoundS();
	
	// stop if the current buffer is playing
	if( bPlaying == TRUE )
	{
        PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
		Stop();
	}

	if( !Load( strFileName ) )	
		return FALSE;

#ifdef	__TEST_SOUND__
		ASSERT( nID != WAVE_OBJECT_NONE );
		ASSERT( lpDSBStreamBuffer );
#endif

    // Ensure that position is at 0, ready to go
	// set position
    if( lpDSBStreamBuffer->SetCurrentPosition( pos ) != DS_OK )
		return FALSE;
	// set volume
    if( lpDSBStreamBuffer->SetVolume( DS_nVolume ) != DS_OK )
		return FALSE;
	// set pan
    if( lpDSBStreamBuffer->SetPan( DS_nPan ) != DS_OK )
		return FALSE;

	// play
    if( lpDSBStreamBuffer->Play( 0, 0, dwFlags ) != DS_OK )
		return FALSE;

	bPlaying = TRUE;
	bLoopFile = dwFlags;

	return TRUE;
}

// stop playing
// if has stoped, no effects
void WAVESTATIC::Stop()
{
    HRESULT dsrval;

//	WaitForSingleObject( hMutex, INFINITE );
#ifdef	__TEST_SOUND__
	ASSERT( bPlaying );
#endif

    if( bPlaying )
    {
        bPlaying = FALSE;
		dsrval = lpDSBStreamBuffer->Stop();
//		ReleaseMutex( hMutex );
		Close();
//		WaitForSingleObject( hMutex, INFINITE );
    }
//	ReleaseMutex( hMutex );
	return;
}

BOOL WAVESTATIC::IfPlaying()
{
	HRESULT	dsrval;
	DWORD dwStatus;
	if( lpDSBStreamBuffer == NULL )	return FALSE;
	dsrval = lpDSBStreamBuffer->GetStatus( &dwStatus );
	if ( DS_OK != dsrval ) return FALSE;
	if( !(dwStatus & DSBSTATUS_PLAYING) )
	{
		// must be sendmessage, cannot use postmessage
		// LPARAM	:	1 if it is static wave object
	    SendMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)nID, (LPARAM)1 );
		Stop();
		return FALSE;
	}
	return TRUE;
}

// nIndex		:	ID in global wave array
// return value	:	0 if succeeded, otherwise error number,
int StreamBufferSetupS( int nIndex )
{
	DWORD dwSamples;
    DSBUFFERDESC dsbd;
    HRESULT      dsRetVal;
    LPBYTE       lpWrite1, lpWrite2;
    DWORD        dwLen1, dwLen2;
	int nChkErr = 0;

	WAVESTATIC * lpswWave = NULL;
	lpswWave = SetToGlobalS( nIndex );

	// open the whole wave file, read data to pbData, and close it
	if( WaveLoadFile( lpswWave->strFileName, &lpswWave->cbSize, 
			&dwSamples, &lpswWave->pwfx, &lpswWave->pbData ) != 0 )
	{
        nChkErr =  ERR_WAVE_OPEN_FAILED;
	    //SoundFail( DS_hwndGame, nChkErr );
		goto END_SETUP;
	}

	// test if the format is correct
    if( lpswWave->pwfx->wFormatTag != WAVE_FORMAT_PCM )
    {
		nChkErr = ERR_WAVE_INVALID_FORMAT;
        //SoundFail( DS_hwndGame, nChkErr );
		goto END_SETUP;
    }

    /*
     * Create the secondary DirectSoundBuffer object to receive our sound data.
     */
    memset( &dsbd, 0, sizeof( DSBUFFERDESC ));
    dsbd.dwSize = sizeof( DSBUFFERDESC );
    dsbd.dwFlags = DSBCAPS_CTRLDEFAULT;
    dsbd.dwBufferBytes = lpswWave->cbSize;

#ifdef	__TEST_SOUND__
	ASSERT( lpwsWaves[nIndex] == lpswWave );
#endif

    /* Set Format properties according to the WAVE file we just opened */
	//LPDIRECTSOUNDBUFFER     lpDSB = NULL;
    dsbd.lpwfxFormat = lpswWave->pwfx;
    dsRetVal = lpDS->CreateSoundBuffer( &dsbd,
                                        &lpswWave->lpDSBStreamBuffer,
                                        NULL );
    if( dsRetVal != DS_OK )
    {
		nChkErr = ERR_CREATEDSB_FAILED;
        //SoundFail( DS_hwndGame, nChkErr );
		goto END_SETUP;
    }
/*
	// set wave format 
    if ((dsRetVal = lpDSBPrimary->SetFormat(&wfx)) != DS_OK)
	{
		nChkErr = ERR_WAVE_FORMAT_INVALID;
		SoundFail( DS_hwndGame, nChkErr );
		goto END_SETUP;
	}
*/
	// lock buffer and copy sound data to it
    dsRetVal = lpswWave->lpDSBStreamBuffer->Lock( 0, lpswWave->cbSize,
								               (void**)&lpWrite1, (&dwLen1),
											   (void**)&lpWrite2, (&dwLen2),
											   0 );
    if( dsRetVal != DS_OK )
    {
		nChkErr = ERR_CREATEDSB_LOST;
        //SoundFail( DS_hwndGame, nChkErr );
		lpswWave->lpDSBStreamBuffer->Release();
		lpswWave->lpDSBStreamBuffer = NULL;
		goto END_SETUP;
    }

	// copy data
	memcpy( lpWrite1, lpswWave->pbData, dwLen1 );
	memcpy( lpWrite2, lpswWave->pbData+dwLen1, dwLen2 );

	// unlock
    dsRetVal = lpswWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
                                        (LPVOID)lpWrite2, 0 );

	// LPARAM	:	0 if it is dynamic wave object
    SendMessage( DS_hwndGame, WM_DSSTREAM_PROGRESS, 0L, 0L );
	nChkErr = 0;
END_SETUP:
	
	return nChkErr;
}

void StreamBufferReleaseS( int nIndex )
{
	WAVESTATIC * lpswWave = NULL;
	lpswWave = SetToGlobalS( nIndex );

	// release sound buffer, and unregister from global array
	// wave file has been closed in Load()
	// just free some data
	GlobalFree(lpswWave->pwfx);	lpswWave->pwfx = NULL;
	GlobalFree(lpswWave->pbData); lpswWave->pbData = NULL;

	if( lpswWave->lpDSBStreamBuffer )
		lpswWave->lpDSBStreamBuffer->Release();
	lpswWave->lpDSBStreamBuffer = NULL;
}

LPWAVESTATIC SetToGlobalS( int nIndex )
{
	return lpwsWaves[nIndex];
}

// for static wave only
// called if the static sound buffer got the end
// clear all the sounds played prviously, and now they are stoped.
void DS_CloseStopedSoundS()
{
	HRESULT	dsrval;
	// close static sound buffers that previously opened.
	for( int i=0; i<WAVE_OBJECT_MAXS; i++ )
	{
		if( lpwsWaves[i] != NULL )
		{	
			DWORD dwStatus;
#ifdef	__TEST_SOUND__
			ASSERT( lpwsWaves[i]->nID != WAVE_OBJECT_NONE );
#endif
			dsrval = lpwsWaves[i]->lpDSBStreamBuffer->GetStatus( &dwStatus );
		    if ( DS_OK != dsrval ) continue;
			if( !(dwStatus & DSBSTATUS_PLAYING) )
			{
				// must be sendmessage, cannot use postmessage
				// LPARAM	:	1 if it is static wave object
	            SendMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)lpwsWaves[i]->nID, (LPARAM)1 );
				lpwsWaves[i]->Stop();
			}
		}
	}
}
//////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -