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

📄 dsapi.cpp

📁 赤壁之战的游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                     * 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;
                    dwLen1 -= uChkErr;
                    nChkErr = WaveStartDataRead( &lpwiWave->hmmio,
                                                    &lpwiWave->mmck,
                                                    &lpwiWave->mmckInRIFF );
                    nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1,
                                            lpTemp,
                                            &lpwiWave->mmck, &uChkErr );
                    } while( uChkErr < dwLen1 );
                }
            else
                {
                lpwiWave->bFoundEnd = TRUE;
                lpwiWave->nRemainingSegments = (int)(uChkErr /
                                                    lpwiWave->dwBufferSegSize);
//                DPF( 3,"Setting bFoundEnd in load, nRemSegs = %i, dwBuffSegSize = %u",
  //                      lpwiWave->nRemainingSegments, lpwiWave->dwBufferSegSize );
                memset( (lpWrite1+uChkErr),
                                lpwiWave->pwfx->wBitsPerSample == 8 ? 128 : 0,
                                (dwLen1 - uChkErr));
                }
            }
        }

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

    dsRetVal = lpwiWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
                                        (LPVOID)lpWrite2, 0 );

#ifdef	__TEST_SOUND__
	ASSERT( lpwiWave->lpDSBStreamBuffer );
#endif
#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

    lpwiWave->dwNextWriteOffset = lpwiWave->dwPlayLast = lpwiWave->dwProgress = 0;
    lpwiWave->bDonePlaying = FALSE;
    lpwiWave->bLoopFile = FALSE;

#ifdef	__TEST_SOUND__
	ASSERT( lpwiWave->lpDSBStreamBuffer );
#endif
#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[nIndex] == lpwiWave );
#endif

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

/*****************************************************************************/
/* StreamBufferRelease()                                                     */
/*																			 */
/*  close Stream wave file, and kill timer if nessacary.                     */
/*                                                                           */
/*****************************************************************************/
// nIndex	:	ID in global wave array
void StreamBufferRelease( int nIndex )
{
	LPWAVEDYNAMIC lpwiWave = NULL;

	// set lpwdWaves[nIndex] to lpwiWave
	// so that you can use lpwiWave directly
	lpwiWave = SetToGlobal( nIndex );

	WaveCloseReadFile( &lpwiWave->hmmio, &lpwiWave->pwfx );
#ifdef	__TEST_SOUND__
	ASSERT( lpwiWave->lpDSBStreamBuffer );
#endif
	if( lpwiWave->lpDSBStreamBuffer )
		lpwiWave->lpDSBStreamBuffer->Release();
	lpwiWave->lpDSBStreamBuffer = NULL;

}

/*****************************************************************************/
/* ResetWavePlayer()                                                         */
/*                                                                           */
/*  Performs a subset of the above operations (in StreamBufferSetup). Things */
/* not done include creating a DSB and opening the file (it's already open). */
/*                                                                           */
/*****************************************************************************/
// nIndex	:	ID in global wave array
void ResetWavePlayer( int nIndex )
{
    LPBYTE      lpWrite1, lpWrite2;
    DWORD       dwLen1, dwLen2;
    UINT        uChkErr;
    int         nChkErr;
    HRESULT     dsrval;
	
	LPWAVEDYNAMIC lpwiWave = NULL;

	// set lpwdWaves[nIndex] to lpwiWave
	// so that you can use lpwiWave directly
	lpwiWave = SetToGlobal( nIndex );

    WaveStartDataRead( &lpwiWave->hmmio, &lpwiWave->mmck, &lpwiWave->mmckInRIFF );
    lpwiWave->bFoundEnd = FALSE;
    lpwiWave->nRemainingSegments = 0;

    dsrval = lpwiWave->lpDSBStreamBuffer->Lock( 0, lpwiWave->dwBufferSize,
                                      (void**)&lpWrite1, &dwLen1,
                                      (void**)&lpWrite2, &dwLen2,
                                      0 );

	if( dsrval != DS_OK )
	{
		char	errStr[129];
		switch ( dsrval )
		{
		case	DSERR_BUFFERLOST: 
			strcpy(errStr, "DSERR_BUFFERLOST" );
			break;
		case	DSERR_INVALIDPARAM:
			strcpy(errStr, "DSERR_INVALIDPARAM" );
			break;
		case	DSERR_INVALIDCALL:
			strcpy(errStr, "DSERR_INVALIDCALL" );
			break;
		case	DSERR_PRIOLEVELNEEDED:
			strcpy(errStr, "DSERR_PRIOLEVELNEEDED" );
			break;
		}
		strcat( errStr, "\n" );
		//OutputDebugString( "TimeFunc() could not lock DirectSoundBuffer" );
		OutputDebugString( errStr );
        return;
	}
    if( dwLen1 )
        {
        nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1, lpWrite1,
                                &lpwiWave->mmck, &uChkErr );
        if( uChkErr < dwLen1 )
            {
            if( lpwiWave->bLoopFile )
                {
    /* If the file is shorter than the buffer and we're looping, we need to
     * read the file in again so that we don't get a block of silence before
     * the timer loops playback.
     */
                LPBYTE lpTemp = lpWrite1;

                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;
                    dwLen1 -= uChkErr;
                    nChkErr = WaveStartDataRead( &lpwiWave->hmmio,
                                                    &lpwiWave->mmck,
                                                    &lpwiWave->mmckInRIFF );
                    nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1,
                                            lpTemp,
                                            &lpwiWave->mmck, &uChkErr );
                    } while( uChkErr < dwLen1 );
                }
            else
                {
                lpwiWave->bFoundEnd = TRUE;
                lpwiWave->nRemainingSegments = (int)(uChkErr / lpwiWave->dwBufferSegSize);
//                DPF( 3,"Setting bFoundEnd in load, nRemSegs = %i, dwBuffSegSize = %u",
  //                      lpwiWave->nRemainingSegments, lpwiWave->dwBufferSegSize );

                // Cover ourselves by filling the rest of the buffer space
                // with 8 or 16 bit silence, in case we can't stop the playback
                // exactly on a block boundary and we run a bit into NULL data
                memset(( lpWrite1 + uChkErr),
                                lpwiWave->pwfx->wBitsPerSample == 8 ? 128 : 0,
                                dwLen1 - uChkErr);
                }
            }
        }
    dsrval = lpwiWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
                                        (LPVOID)lpWrite2, 0 );
    lpwiWave->dwNextWriteOffset = lpwiWave->dwPlayLast = lpwiWave->dwProgress = 0;
    lpwiWave->bDonePlaying = FALSE;
	// LPARAM	:	0 if it is dynamic wave object
    SendMessage( DS_hwndGame, WM_DSSTREAM_PROGRESS, 0L, 0L );

}

// nIndex	:	ID in global wave array
void CALLBACK TimeFunc( UINT uTimerID, UINT uMsg, DWORD dwUser,
                                                        DWORD dw1, DWORD dw2 )
{
    static      bInTimer = FALSE;
    LPBYTE      lpWrite1, lpWrite2, lpTemp;
    DWORD       dwLen1, dwLen2, dwPlay, dwWrite;
    int         nChkErr;
    UINT        uChkErr;

	HRESULT		dsrval;
	LPWAVEDYNAMIC lpwiWave = NULL;

    if( bInTimer )
        {
        return;
        }
    else
        {
        bInTimer = TRUE;
        }

	WaitForSingleObject( hMutex, INFINITE );

	// set lpwdWaves[nIndex] to lpwiWave
	// so that you can use lpwiWave directly
	lpwiWave = SetToGlobal( dwUser );

	// very rarely to meet this situation
	// if the thread is stoping the wave, and this function begin to wait,
	// when stoped, the dwUser is invalid, and lpwiWave is invalid too.
	// so must test if should quit.
	if( !lpwiWave )
	{
		OutputDebugString( "DS dynamic error: just begin to play when stop wave!\n" );
		//-----debug
#ifdef	_DS_LOG_
		FILE*fp=fopen( "DSTest.log","at" );
		fprintf(fp,"A" );
		fclose(fp);
#endif
		//-----debug
		goto END_TIME;
	}

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

    /* Get and print the current position of the play cursor */
    lpwiWave->lpDSBStreamBuffer->GetCurrentPosition( &dwPlay, &dwWrite );

    if(( lpwiWave->dwNextWriteOffset < dwPlay )
        && (( lpwiWave->dwNextWriteOffset + lpwiWave->dwBufferSegSize ) > dwPlay ))
    {
/*		OutputDebugString( "DS dynamic error: Write offset!\n" );
		//-----debug
		FILE*fp=fopen( "DSTest.log","at" );
		fprintf(fp,"B" );
		fclose(fp);
		//-----debug
*/
        goto END_TIME;
    }

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

    /* Have we found the end of the file and passed the buffer end? */
    if( lpwiWave->bFoundEnd && !lpwiWave->nRemainingSegments )
    {
        if( !lpwiWave->bDonePlaying )
        {
            PostMessage( DS_hwndGame, WM_DSSTREAM_DONE, (WPARAM)lpwiWave->nID, (LPARAM)0 );
            //lpwiWave->bDonePlaying = TRUE;
			lpwiWave->Stop();
        }
        goto END_TIME;
    }

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

    if( dwPlay < lpwiWave->dwPlayLast )
        lpwiWave->dwProgress += (dwPlay + lpwiWave->dwBufferSize - lpwiWave->dwPlayLast);
    else
        lpwiWave->dwProgress += (dwPlay - lpwiWave->dwPlayLast);
    lpwiWave->dwPlayLast = dwPlay;
    PostMessage( DS_hwndGame, WM_DSSTREAM_PROGRESS, 0L, 0L );

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

    /*
     *  If lpwiWave->bFoundEnd == TRUE, then we've finished reading in the file,
     * but we need to wait until the buffer's play cursor passes the point we
     * were at when we found out we were done reading.
     */
    if( lpwiWave->bFoundEnd && lpwiWave->nRemainingSegments )
        {
        lpwiWave->nRemainingSegments--;

        if( lpwiWave->nRemainingSegments > 1 ) {
        dsrval = lpwiWave->lpDSBStreamBuffer->Lock( lpwiWave->dwNextWriteOffset,
                                            lpwiWave->dwBufferSegSize,
                                            (void**)&lpWrite1, &dwLen1,
                                            (void**)&lpWrite2, &dwLen2,
                                            0 );

		if( dsrval != DS_OK )
        {
			char	errStr[129];
			switch ( dsrval )
			{
			case	DSERR_BUFFERLOST: 
				strcpy(errStr, "DSERR_BUFFERLOST" );
				break;
			case	DSERR_INVALIDPARAM:
				strcpy(errStr, "DSERR_INVALIDPARAM" );
				break;
			case	DSERR_INVALIDCALL:
				strcpy(errStr, "DSERR_INVALIDCALL" );
				break;
			case	DSERR_PRIOLEVELNEEDED:
				strcpy(errStr, "DSERR_PRIOLEVELNEEDED" );
				break;
			}
			strcat( errStr, "\n" );
			//OutputDebugString( "TimeFunc() could not lock DirectSoundBuffer" );
			//-----debug
#ifdef	_DS_LOG_
			FILE*fp=fopen( "DSTest.log","at" );
			fprintf(fp,"C" );
			fclose(fp);
#endif
			//-----debug
			OutputDebugString( errStr );
            goto END_TIME;
        }

        if( lpwiWave->pwfx->wBitsPerSample == 8 )
            memset( lpWrite1, 128, dwLen1 );
        else if( lpwiWave->pwfx->wBitsPerSample == 16 )
            memset( lpWrite1, 0, dwLen1 );
        lpwiWave->lpDSBStreamBuffer->Unlock( (LPVOID)lpWrite1, dwLen1,
                                          (LPVOID)lpWrite2, dwLen2 );
    /*
     * This code is stolen from the end of the routine -- we need to keep
     * zeroing out buffer segments while we're waiting for the play cursor to
     * catch up to the end of the WAVE data.
     */
        lpwiWave->dwNextWriteOffset += lpwiWave->dwBufferSegSize;
        if( lpwiWave->dwNextWriteOffset >= lpwiWave->dwBufferSize )
            lpwiWave->dwNextWriteOffset -= lpwiWave->dwBufferSize;
        }
        goto END_TIME;
        }

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

    /* Lock a segment of memory that is behind the play cursor */
    if( ( dsrval = lpwiWave->lpDSBStreamBuffer->Lock( lpwiWave->dwNextWriteOffset,
                                        lpwiWave->dwBufferSegSize,
                                        (void**)&lpWrite1, &dwLen1,
                                        (void**)&lpWrite2, &dwLen2,
                                        0 ) ) != DS_OK )
        {
		char	errStr[129];
		switch ( dsrval )
		{
		case	DSERR_BUFFERLOST: 
			strcpy(errStr, "DSERR_BUFFERLOST" );
			break;
		case	DSERR_INVALIDPARAM:
			strcpy(errStr, "DSERR_INVALIDPARAM" );
			break;
		case	DSERR_INVALIDCALL:
			strcpy(errStr, "DSERR_INVALIDCALL" );
			break;
		case	DSERR_PRIOLEVELNEEDED:
			strcpy(errStr, "DSERR_PRIOLEVELNEEDED" );
			break;
		}
		strcat( errStr, "\n" );
        //OutputDebugString( "TimeFunc() could not lock DirectSoundBuffer" );
		//-----debug
#ifdef	_DS_LOG_
		FILE*fp=fopen( "DSTest.log","at" );
		fprintf(fp,"D" );
		fclose(fp);
#endif
		//-----debug
		OutputDebugString( errStr );
        goto END_TIME;
        }
        
#ifdef	__TEST_SOUND__
	ASSERT( lpwdWaves[dwUser] == lpwiWave );
#endif

    if( dwLen1 && !lpwiWave->bDonePlaying )
        {
        nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1, lpWrite1,
                                &lpwiWave->mmck, &uChkErr );
        if( uChkErr < (UINT)dwLen1 )
            {
            if( !lpwiWave->bLoopFile )
                {
                /* Zero out the rest of this block */
                if( lpwiWave->pwfx->wBitsPerSample == 8 )
                    memset( lpWrite1+uChkErr, 128, ((UINT)dwLen1-uChkErr));
                else if( lpwiWave->pwfx->wBitsPerSample == 16 )
                    memset( lpWrite1+uChkErr, 0, ((UINT)dwLen1-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 = lpWrite1;
                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;
                    dwLen1 -= uChkErr;
                    nChkErr = WaveStartDataRead( &lpwiWave->hmmio,
                                                    &lpwiWave->mmck,
                                                    &lpwiWave->mmckInRIFF );
					// added by Liu Gang, Aug 13, 1997
					// to fix a bug
					if( nChkErr != 0 )	break;
                    nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen1,
                                            lpTemp,
                                            &lpwiWave->mmck, &uChkErr );
					// added by Liu Gang, Aug 13, 1997
					if( nChkErr != 0 )	break;
                    } while( uChkErr < dwLen1 );
                }
            }
        }
    /*
    * The bDonePlaying flag is set by the caller if the user stops playback
    * before the end of the WAVE file is encountered.  It tells us to cut this
    * racket out and play nothing in case it takes the caller a couple
    * interrupts to shut off the timer.
    */
    else if( dwLen1 && lpwiWave->bDonePlaying )
        {
        // Set the appropriate silence value
        memset( lpWrite1,
                    lpwiWave->pwfx->wBitsPerSample == 8 ? 128 : 0,
                    dwLen1);
        }

    if( dwLen2 && !lpwiWave->bDonePlaying )
        {
        nChkErr = WaveReadFile( lpwiWave->hmmio, (UINT)dwLen2, lpWrite2,
                                &lpwiWave->mmck, &uChkErr );
        if( uChkErr < (UINT)dwLen2 )
            {
            if( !lpwiWave->bLoopFile )

⌨️ 快捷键说明

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