static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *win32_visual)
/*vo_driver_t *init_video_out_plugin( config_values_t * config, void * win32_visual )*/
{

	/* Make sure that the DirectX drivers are available and present! */
	/* Not complete yet */

	win32_driver_t * win32_driver = ( win32_driver_t * ) malloc ( sizeof( win32_driver_t ) );
	memset( win32_driver, 0, sizeof( win32_driver_t ) );

	win32_driver->win32_visual						= win32_visual;
	win32_driver->vo_driver.get_capabilities		= win32_get_capabilities;
	win32_driver->vo_driver.alloc_frame				= win32_alloc_frame ;
	win32_driver->vo_driver.update_frame_format		= win32_update_frame_format;
	win32_driver->vo_driver.display_frame			= win32_display_frame;
	win32_driver->vo_driver.overlay_blend			= win32_overlay_blend;
	win32_driver->vo_driver.get_property			= win32_get_property;
	win32_driver->vo_driver.set_property			= win32_set_property;
	win32_driver->vo_driver.get_property_min_max	= win32_get_property_min_max;
	win32_driver->vo_driver.gui_data_exchange		= win32_gui_data_exchange;
	win32_driver->vo_driver.dispose					= win32_exit;
    win32_driver->vo_driver.redraw_needed           = win32_redraw_needed;

	CreatePrimary( win32_driver );
	if( !CheckPixelFormat( win32_driver ) )
	{
		Error( 0, "vo_directx : Your screen pixel format is not supported" );
		Destroy( win32_driver );
		return 0;
	}

#if (NEW_YUV)
	win32_driver->yuv2rgb_factory = yuv2rgb_factory_init( win32_driver->mode, 0, 0 );
	win32_driver->yuv2rgb = win32_driver->yuv2rgb_factory->create_converter(win32_driver->yuv2rgb_factory);
#else
	win32_driver->yuv2rgb = yuv2rgb_init( win32_driver->mode, 0, 0 );
#endif

	return ( vo_driver_t * ) win32_driver;
}    
Example #2
0
BOOL DLL_EXPORT CreatePartition(PPARTITION_ENTRY ppeParEntry, 
								  BYTE btHardDisk, 
								  DWORD dwFlag,
								  BOOL blIsFormat, 
								  PBYTE pLabel, 
								  HWND hWnd,
								  PINT pnError)
{
	int						nErrorCode;
	PARTITION_INFORMATION	pi,piExtend;
	DRIVE_LAYOUT			DriveLayout;
	DISK_GEOMETRY			dg;
	int						nIndex;
	BYTE					btPartitionType;
	BOOL					bExistExtend;
	BOOL					bNeedResize,bResizeSuccess;
	LARGE_INTEGER			lnExtendStart,lnExtendEnd;
	char					chDriveLetter;
	char					szLabel[12];
//	int						nLogicalNumber;

	btHardDisk &= 0x7f;	
	//Get disk geomtry and layout information
	*pnError = nErrorCode = ERR_PARMAN_PARAM; // 102 indicate false
	if ( GetDiskGeometry(btHardDisk,&dg))
		return FALSE;
	if ( GetDriveLayout(btHardDisk, &DriveLayout))
		return FALSE;
	//check if usb sigle partition
	if((DriveLayout.dli.PartitionCount % 4) != 0 )
		return FALSE;

	//translate to partition information
	memset(&pi,0,sizeof(PARTITION_INFORMATION));
	pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector * dg.BytesPerSector;
	pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition * dg.BytesPerSector;
	pi.BootIndicator = ppeParEntry->BootFlag ? 1:0;
	pi.PartitionType = ppeParEntry->SystemFlag;
	
	*pnError = ERR_PARMAN_PARAM;
	//stat logical drive numbers
//	nLogicalNumber = 0;
//	for( nIndex = 4 ; nIndex < DriveLayout.dli.PartitionCount ; nIndex +=4 )
//	{
//		if ( GetPartitionType( &DriveLayout,nIndex) != DISKMAN_PAR_UNUSED )
//			nLogicalNumber++;
//	}
	//detect if exist extend partition
	bExistExtend = FALSE;
	for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
	{
		if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR )
		{
			bExistExtend = TRUE;
			memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex],
					sizeof(PARTITION_INFORMATION));
			lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart;
			lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart;
			lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1;
			break;
		}
	}
	//do alignment
	if ( dwFlag == LOGICAL )
	{
		LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR);
	}else
		LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR);
	//create partition	
	bNeedResize = FALSE;
	bResizeSuccess = TRUE;
	if( dwFlag == LOGICAL )
	{
		if( bExistExtend )
		{
			//beyond the extend low boundary
			if(	pi.StartingOffset.QuadPart  
				<
				lnExtendStart.QuadPart )
			{
				//justify the extend head
				piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart;
				piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
													- piExtend.StartingOffset.QuadPart
													+ 1;
				bNeedResize = TRUE;
			}
			//beyond the extend high boundary
			if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
				> 
				lnExtendEnd.QuadPart + 1 )
			{
				//justify the extend end
				//piExtend.StartingOffset has modified;
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													+ pi.PartitionLength.QuadPart
													- piExtend.StartingOffset.QuadPart;
				bNeedResize = TRUE;
			}
			//if there existing only one logical drive is required to
			//move to the free space acrross a primary partition, parman
			//should move the extend with the logical
//			if( nLogicalNumber == 1 )
//			{
//				if(	pi.StartingOffset.QuadPart  
//					<
//					lnExtendStart.QuadPart )
//
//				if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
//				> 
//				lnExtendEnd.QuadPart + 1 )
//			}
			if ( bNeedResize )
			{
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				bResizeSuccess = ! nErrorCode;
			}
			//resize success create logical
			if( bResizeSuccess )
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
		}else
		{
			//no extend partition, should create one
			//Backup partition type;
			btPartitionType = pi.PartitionType;
			pi.PartitionType = PARTITION_EXTENDED;
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
			if( !nErrorCode ) 
			{
				pi.PartitionType = btPartitionType;
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}
	}else
	{
		// if primary overlap the extend then resize extend partition
		if( bExistExtend )
		{
			if( IsOverlap(&piExtend,&pi) )
			{
				//try to resize extend partition forward
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													- lnExtendStart.QuadPart;
				//if length < 0 then length = 0
				if( piExtend.PartitionLength.QuadPart < 0 )
					piExtend.PartitionLength.QuadPart = 0;
				//resize forward
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				if( nErrorCode != 0 )
				{
					//try to resize backward
					piExtend.StartingOffset.QuadPart =  pi.StartingOffset.QuadPart
														+ pi.PartitionLength.QuadPart;
					piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
														- piExtend.StartingOffset.QuadPart
														+ 1;
					nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
					
					bResizeSuccess = ! nErrorCode;
				}
			}
		}

		if( bResizeSuccess )
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
	}
	//create success, write back
	if( !nErrorCode )
		nErrorCode = SetDriveLayout(btHardDisk,&DriveLayout);
	//format partition
	if(( blIsFormat )&&( !nErrorCode ))
	{
		for( nIndex = 0; nIndex < 100 ; nIndex++ )
		{
			Sleep(500);
			chDriveLetter = RetrieveDriveLttr(btHardDisk,
												dwFlag,
												(DWORD)
												(pi.StartingOffset.QuadPart
													/ dg.BytesPerSector));

			if( (BYTE)chDriveLetter != 0xff )
			{
				chDriveLetter += 0x40;
				break;
			}
		}
		if ( chDriveLetter >= 'A' && chDriveLetter <= 'Z' )
		{
			memcpy(szLabel,pLabel,11);
			szLabel[11] = '\0';
			//if no name
			if( !memcmp(szLabel,"NO NAME",7))
				szLabel[0] = '\0';
			switch( pi.PartitionType & 0x0f)
			{
			case 0x01://fat12
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd);
				break;
			case 0x04://fat16(old)
			case 0x06://fat16(big dos)
			case 0x0e://fat16(eint13)
			case 0x0f://fat16(int13)
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			case 0x07://ntfs
				FormatDrive(chDriveLetter, szLabel,FORMAT_NTFS,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			case 0x0b://fat32(int13)
			case 0x0c://fat32(eint13)
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_32,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			default:
				//unknow type
				break;
			}
		}
	}
	*pnError = nErrorCode;
	return !nErrorCode;
}
Example #3
0
BOOL DLL_EXPORT	GetProtectSectors(BYTE					btHardDisk,
								  DWORD					dwStartSector,
								  CREATE_PAR_FLAG		flags,//indicate is logical or primary
								  DWORD					dwFlag,//create flags
								  PPARTITION_ENTRY		ppeParEntry,
								  PPROTECT_SECTOR		pProtect,//[out]
								  BOOL					bWriteToDisk,									
								  int					*pnError)
{
	DISK_GEOMETRY				dg;
	DRIVE_LAYOUT				DriveLayout;
	int							nErrorCode; 
	int							nIndex;
	LARGE_INTEGER				lnStartByte;
	BOOL						bDeleteSuccess;
	PARTITION_INFORMATION		pi,piExtend;
	BYTE						btPartitionType;
	BOOL						bExistExtend,bNeedResize,bResizeSuccess;
	LARGE_INTEGER				lnExtendStart,lnExtendEnd;
	//viriable need to get the protect sectors
	BOOL						bIsDeleteLogical;
	BOOL						bIsCreateLogical;
	DWORD						dwExtOriginalHead,dwExtFinalHead;
	DWORD						dwOriginalHead,dwOriginalEnd;
	DWORD						dwFinalHead,dwFinalEnd;
	DWORD						dwOriginalEmbr,dwFinalEmbr;

	//p//init protect logic viriables
	memset( pProtect, 0, sizeof(PROTECT_SECTOR));
	bIsDeleteLogical = FALSE;
	bIsCreateLogical = FALSE;
	dwExtOriginalHead = 0;
	dwExtFinalHead = 0;
	dwOriginalHead = 0;
	dwOriginalEnd = 0;
	dwFinalHead = 0;
	dwFinalEnd = 0;
	dwOriginalEmbr = 0;
	dwFinalEmbr = 0;

	btHardDisk &= 0x7f;	
	bDeleteSuccess = FALSE;
	// 102 indicate false
	*pnError = nErrorCode = ERR_PARMAN_PARAM;
	//Get disk geometry and layout information
	if ( GetDiskGeometry(btHardDisk,&dg))
		return FALSE;
	if ( GetDriveLayout(btHardDisk, &DriveLayout))
		return FALSE;

	/************************************************
		Delete partition
	************************************************/
	//look for the partition
	lnStartByte.QuadPart = (__int64)dg.BytesPerSector * dwStartSector;
	for( nIndex = DriveLayout.dli.PartitionCount -1 ; nIndex >=0 ; nIndex-- )
	{
		if(DriveLayout.dli.PartitionEntry[nIndex].StartingOffset.QuadPart 
			== lnStartByte.QuadPart)
			break;
	}
	//usb disk
	if( ( DriveLayout.dli.PartitionCount == 1 ) && ( nIndex == 0 ) )
	{
		//p//back up the partition information
		memcpy(&pi,
				&DriveLayout.dli.PartitionEntry[nIndex],
				sizeof(PARTITION_INFORMATION));

		//zero partition table
		memset(	DriveLayout.dli.PartitionEntry,
				0,
				4*sizeof(PARTITION_INFORMATION) );
		
		DriveLayout.dli.PartitionCount = 4;
		
		for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
			DriveLayout.dli.PartitionEntry[nIndex].RewritePartition = TRUE;

		bDeleteSuccess = TRUE;
	}else
	{
		//if found do delete
		if(nIndex >= 0)
		{
			switch( GetPartitionType(&DriveLayout, nIndex) )
			{
			case DISKMAN_PAR_UNUSED:
				break;
			case DISKMAN_PAR_EXTENDED_MBR:
				if ( flags.Extended )
				{
					//delete first logical
					nIndex = 4;
					//p//back up the partition information
					memcpy(&pi,
							&DriveLayout.dli.PartitionEntry[nIndex],
							sizeof(PARTITION_INFORMATION));

					bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex);
					bIsDeleteLogical = TRUE;
					break;
				}
				//else consider as primary
			case DISKMAN_PAR_PRIMARY_MBR:
				//p//back up the partition information
				memcpy(&pi,
						&DriveLayout.dli.PartitionEntry[nIndex],
						sizeof(PARTITION_INFORMATION));

				bDeleteSuccess = !DeletePrimary(&DriveLayout,nIndex);
				break;
			case DISKMAN_PAR_EXTENDED_EMBR:
				nIndex +=3;
			case DISKMAN_PAR_LOGICAL_EMBR:
				//p//back up the partition information
				memcpy(&pi,
						&DriveLayout.dli.PartitionEntry[nIndex],
						sizeof(PARTITION_INFORMATION));

				bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex);
				bIsDeleteLogical = TRUE;
				break;
			}
		}//if nIndex >= 0;
	}
	//delete fail
	if( bDeleteSuccess )
	{
		//p//pi now store the original start and end
		dwOriginalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector);
		dwOriginalEnd = dwOriginalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector);
		if( bIsDeleteLogical )
			dwOriginalEmbr = dwOriginalHead - pi.HiddenSectors;//dwOriginalEmbr == embr
	}else
	{
		return FALSE;
	}
	/************************************************
		Create partition
	************************************************/
	//check if usb sigle partition
	if((DriveLayout.dli.PartitionCount % 4) != 0 )
		return FALSE;

	//translate to partition information
	memset(&pi,0,sizeof(PARTITION_INFORMATION));
	//bootable?
	pi.BootIndicator = ppeParEntry->BootFlag ? 1:0;
	//file system
	pi.PartitionType = ppeParEntry->SystemFlag;
	//start
	pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector 
											* dg.BytesPerSector;
	//length
	pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition
											* dg.BytesPerSector;
	
	//detect if exist extend partition
	bExistExtend = FALSE;
	for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
	{
		if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR )
		{
			bExistExtend = TRUE;
			memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex],
					sizeof(PARTITION_INFORMATION));
			lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart;
			lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart;
			lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1;
			//p//Get extend original start
			dwExtOriginalHead = (DWORD)(lnExtendStart.QuadPart / dg.BytesPerSector);
			break;
		}
	}
	//do alignment
	if ( dwFlag == LOGICAL )
	{
		LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR);
	}else
		LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR);
	
	bNeedResize = FALSE;
	bResizeSuccess = TRUE;
	if( dwFlag == LOGICAL )
	{
		bIsCreateLogical = TRUE;
		if( bExistExtend )
		{
			//beyond the extend low boundary
			if(	pi.StartingOffset.QuadPart  
				<
				lnExtendStart.QuadPart )
			{
				//justify the extend head
				piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart;
				piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
													- piExtend.StartingOffset.QuadPart
													+ 1;
				bNeedResize = TRUE;
			}
			//beyond the extend high boundary
			if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
				> 
				lnExtendEnd.QuadPart + 1 )
			{
				//justify the extend end
				//piExtend.StartingOffset has modified;
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													+ pi.PartitionLength.QuadPart
													- piExtend.StartingOffset.QuadPart;
				bNeedResize = TRUE;
			}
			if ( bNeedResize )
			{
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				bResizeSuccess = ! nErrorCode;
			}
			//resize success create logical
			if( bResizeSuccess )
			{
				//p//get extend final head
				dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector);
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}else
		{
			//no extend partition, should create one
			//Backup partition type;
			btPartitionType = pi.PartitionType;
			pi.PartitionType = PARTITION_EXTENDED;
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
			if( !nErrorCode ) 
			{
				pi.PartitionType = btPartitionType;
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}
	}else
	{
		// if primary overlap the extend then resize extend partition
		if( bExistExtend )
		{
			if( IsOverlap(&piExtend,&pi))
			{
				//try to resize extend partition forward
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													- lnExtendStart.QuadPart;
				//if length < 0 then length = 0
				if( piExtend.PartitionLength.QuadPart < 0 )
					piExtend.PartitionLength.QuadPart = 0;
				//resize forward
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				if( nErrorCode != 0 )
				{
					//try to resize backward
					piExtend.StartingOffset.QuadPart =  pi.StartingOffset.QuadPart
														+ pi.PartitionLength.QuadPart;
					piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
														- piExtend.StartingOffset.QuadPart
														+ 1;
					nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
					
					bResizeSuccess = ! nErrorCode;
				}
			}
		}

		if( bResizeSuccess )
		{
			//p//get extend final head
			dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector);
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
		}
	}
	//get the protect sectors group
	if( !nErrorCode )
	{
		//pi now store the partition information created
		dwFinalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector);
		dwFinalEnd = dwFinalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector);
		if( bIsCreateLogical )
		{
			dwFinalEmbr = dwFinalHead;//dwFinalEmbr == embr
			dwFinalHead += dg.SectorsPerTrack;
		}
		if( dwExtOriginalHead >= dwFinalHead &&
			dwExtOriginalHead <= dwFinalEnd - 1 )
		{
			pProtect->bProtectReadOne = TRUE;
			pProtect->dwProtectReadOne = dwExtOriginalHead;
		}
		if( bIsCreateLogical ^ bIsDeleteLogical )
		{
			//delete primary, create logical or
			//delete logical, create primary
			if( dwExtFinalHead >= dwOriginalHead &&
				dwExtFinalHead <= dwOriginalEnd - 1 )
			{
				pProtect->bProtectWriteOne = TRUE;
				pProtect->dwProtectWriteOne = dwExtFinalHead;
			}
		}
		if(	bIsDeleteLogical )
		{
			if( dwOriginalEmbr >= dwFinalHead &&
				dwOriginalEmbr <= dwFinalEnd - 1 )
			{
				pProtect->bProtectReadTwo = TRUE;
				pProtect->dwProtectReadTwo = dwOriginalEmbr;
			}
			if( bIsCreateLogical )
			{
				//delete logical, create logical
				if( dwFinalEmbr >= dwOriginalHead &&
					dwFinalEmbr <= dwOriginalEnd - 1 )
				{
					pProtect->bProtectWriteTwo = TRUE;
					pProtect->dwProtectWriteTwo = dwFinalEmbr;
				}
			}
		}
	}
	//if write set drive layout
	if( !nErrorCode && bWriteToDisk )
		nErrorCode = SetDriveLayout(btHardDisk, &DriveLayout, TRUE);
	//return
	*pnError = nErrorCode;
	return( nErrorCode == 0 );
}
Example #4
0
static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	HRESULT      result;
	WAVEFORMATEX waveformat;

	/* Set basic WAVE format parameters */
	memset(&waveformat, 0, sizeof(waveformat));
	waveformat.wFormatTag = WAVE_FORMAT_PCM;

	/* Determine the audio parameters from the AudioSpec */
	switch ( spec->format & 0xFF ) {
		case 8:
			/* Unsigned 8 bit audio data */
			spec->format = AUDIO_U8;
			silence = 0x80;
			waveformat.wBitsPerSample = 8;
			break;
		case 16:
			/* Signed 16 bit audio data */
			spec->format = AUDIO_S16;
			silence = 0x00;
			waveformat.wBitsPerSample = 16;
			break;
		default:
			SDL_SetError("Unsupported audio format");
			return(-1);
	}
	waveformat.nChannels = spec->channels;
	waveformat.nSamplesPerSec = spec->freq;
	waveformat.nBlockAlign =
		waveformat.nChannels * (waveformat.wBitsPerSample/8);
	waveformat.nAvgBytesPerSec = 
		waveformat.nSamplesPerSec * waveformat.nBlockAlign;

	/* Update the fragment size as size in bytes */
	SDL_CalculateAudioSpec(spec);

	/* Open the audio device */
	result = DSoundCreate(NULL, &sound, NULL);
	if ( result != DS_OK ) {
		SetDSerror("DirectSoundCreate", result);
		return(-1);
	}

	/* Create the audio buffer to which we write */
	NUM_BUFFERS = -1;
#ifdef USE_PRIMARY_BUFFER
	if ( mainwin ) {
		NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf,
						&waveformat, spec->size);
	}
#endif /* USE_PRIMARY_BUFFER */
	if ( NUM_BUFFERS < 0 ) {
		NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf,
						&waveformat, spec->size);
		if ( NUM_BUFFERS < 0 ) {
			return(-1);
		}
#ifdef DEBUG_SOUND
		fprintf(stderr, "Using secondary audio buffer\n");
#endif
	}
#ifdef DEBUG_SOUND
	else
		fprintf(stderr, "Using primary audio buffer\n");
#endif

	/* The buffer will auto-start playing in DX5_WaitAudio() */
	playing = 0;
	mixlen = spec->size;

#ifdef USE_POSITION_NOTIFY
	/* See if we can use DirectX 6 event notification */
	if ( CreateAudioEvent(this) == 0 ) {
		this->WaitAudio = DX6_WaitAudio_EventWait;
	} else {
		this->WaitAudio = DX5_WaitAudio_BusyWait;
	}
#endif
	return(0);
}