DWORD CAudio::AudioThreadProc() { for (;;) { while (m_bContinue&&DataEmpty()) { DebugPrint("空\n"); WaitForSingleObject(m_hNotEmptyEvent, 100); } if (m_bForce || !m_bContinue && DataEmpty())break; DebugPrint("m_cWaveHdr:index:%u,flags:%u\n", m_dwWaveHdrIndex, m_cWaveHdr[m_dwWaveHdrIndex].dwFlags); if (m_cWaveHdr[m_dwWaveHdrIndex].dwFlags & WHDR_PREPARED) { waveOutUnprepareHeader(m_hWaveOut, m_cWaveHdr + m_dwWaveHdrIndex, sizeof(WAVEHDR)); if (MAX_WAVE_DATA_COUNT == ++m_dwEnd)m_dwEnd = 0; DebugPrint("减小:%u:%u:%u\n", m_dwStart, m_dwCur, m_dwEnd); SetEvent(m_hNotFullEvent); } m_cWaveHdr[m_dwWaveHdrIndex].lpData = m_cData[m_dwCur].data; m_cWaveHdr[m_dwWaveHdrIndex].dwBufferLength = (DWORD)m_cData[m_dwCur].len; if (!m_bAudioStart) { m_bAudioStart = true; SetEvent(m_hStartEvent); while (!m_bVideoStart) WaitForSingleObject(m_hStartEvent, 100); } waveOutPrepareHeader(m_hWaveOut, m_cWaveHdr + m_dwWaveHdrIndex, sizeof(WAVEHDR)); waveOutWrite(m_hWaveOut, m_cWaveHdr + m_dwWaveHdrIndex, sizeof(WAVEHDR)); if (MAX_WAVE_DATA_COUNT == ++m_dwCur)m_dwCur = 0; DebugPrint("中间:%u:%u:%u\n", m_dwStart, m_dwCur, m_dwEnd); if (MAX_WAVE_COUNT == ++m_dwWaveHdrIndex)m_dwWaveHdrIndex = 0; InterlockedIncrement(&m_dwCount); while (m_dwCount >= MAX_WAVE_COUNT)WaitForSingleObject(m_hDataEvent, INFINITE); if (MAX_WAVE_COUNT - 1 != m_dwCount)DebugPrint("%u\n", m_dwCount); } while (m_dwCount)WaitForSingleObject(m_hDataEvent, INFINITE); return 0; }
bool CSave::WriteFields( const char *pname, void *pBaseData, const DataMap_t& dataMap, const TYPEDESCRIPTION *pFields, int fieldCount ) { int i, j; const TYPEDESCRIPTION *pTest; int entityArray[ MAX_ENTITYARRAY ]; // Precalculate the number of empty fields int actualCount = 0; for( i = 0; i < fieldCount; i++ ) { pTest = &pFields[ i ]; void *pOutputData; pOutputData = ( ( char * ) pBaseData + pTest->fieldOffset ); if( ( pTest->flags & TypeDescFlag::SAVE ) && !DataEmpty( ( const char * ) pOutputData, pTest->fieldSize * g_SaveRestoreSizes[ pTest->fieldType ] ) ) ++actualCount; } // Empty fields will not be written, write out the actual number of fields to be written WriteInt( pname, &actualCount, 1 ); for( i = 0; i < fieldCount; i++ ) { void *pOutputData; pTest = &pFields[ i ]; pOutputData = ( ( char * ) pBaseData + pTest->fieldOffset ); // UNDONE: Must we do this twice? //TODO: update CSaveRestoreBuffer to allow seeking to write to earlier locations. - Solokiller if( !( pTest->flags & TypeDescFlag::SAVE ) || DataEmpty( ( const char * ) pOutputData, pTest->fieldSize * g_SaveRestoreSizes[ pTest->fieldType ] ) ) continue; switch( pTest->fieldType ) { case FIELD_FLOAT: WriteFloat( pTest->fieldName, ( float * ) pOutputData, pTest->fieldSize ); break; case FIELD_TIME: WriteTime( pTest->fieldName, ( float * ) pOutputData, pTest->fieldSize ); break; case FIELD_MODELNAME: case FIELD_SOUNDNAME: case FIELD_STRING: WriteString( pTest->fieldName, ( int * ) pOutputData, pTest->fieldSize ); break; case FIELD_CLASSPTR: case FIELD_EVARS: case FIELD_EDICT: case FIELD_ENTITY: case FIELD_EHANDLE: if( pTest->fieldSize > MAX_ENTITYARRAY ) ALERT( at_error, "Can't save more than %d entities in an array!!!\n", MAX_ENTITYARRAY ); for( j = 0; j < pTest->fieldSize; j++ ) { switch( pTest->fieldType ) { case FIELD_EVARS: entityArray[ j ] = EntityIndex( ( ( entvars_t ** ) pOutputData )[ j ] ); break; case FIELD_CLASSPTR: entityArray[ j ] = EntityIndex( ( ( CBaseEntity ** ) pOutputData )[ j ] ); break; case FIELD_EDICT: entityArray[ j ] = EntityIndex( ( ( edict_t ** ) pOutputData )[ j ] ); break; case FIELD_ENTITY: entityArray[ j ] = EntityIndex( ( ( EOFFSET * ) pOutputData )[ j ] ); break; case FIELD_EHANDLE: entityArray[ j ] = EntityIndex( ( CBaseEntity * ) ( ( ( EHANDLE * ) pOutputData )[ j ] ) ); break; } } WriteInt( pTest->fieldName, entityArray, pTest->fieldSize ); break; case FIELD_POSITION_VECTOR: WritePositionVector( pTest->fieldName, ( float * ) pOutputData, pTest->fieldSize ); break; case FIELD_VECTOR: WriteVector( pTest->fieldName, ( float * ) pOutputData, pTest->fieldSize ); break; case FIELD_BOOLEAN: //TODO: should be written as a bit perhaps? - Solokiller WriteBoolean( pTest->fieldName, ( bool* ) pOutputData, pTest->fieldSize ); break; case FIELD_INTEGER: WriteInt( pTest->fieldName, ( int * ) pOutputData, pTest->fieldSize ); break; case FIELD_SHORT: WriteData( pTest->fieldName, 2 * pTest->fieldSize, ( ( char * ) pOutputData ) ); break; case FIELD_CHARACTER: WriteData( pTest->fieldName, pTest->fieldSize, ( ( char * ) pOutputData ) ); break; case FIELD_FUNCPTR: WriteFunction( pTest->fieldName, ( void ** ) pOutputData, pTest->fieldSize, dataMap, *pTest ); break; default: ALERT( at_error, "Bad field type\n" ); } } return true; }