AxibugEmuOnline/virtuanessrc097-master/AviConvDlg.cpp

626 lines
34 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// AVI変換ダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <commdlg.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Config.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "AviConvDlg.h"
#include "nes.h"
#include "mmu.h"
#include "ppu.h"
#include "apu.h"
#include "rom.h"
#include "DirectDraw.h"
CHAR CAviConvDlg::g_szErrorMessage[256];
DLG_MESSAGE_BEGIN(CAviConvDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_TIMER, OnTimer )
DLG_ON_MESSAGE( WM_APP+100, OnConvertDone )
DLG_ON_MESSAGE( WM_APP+101, OnConvertError )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDC_MCV_ROMBROWSE, OnRomFileBrowse )
DLG_ON_COMMAND( IDC_MCV_MOVIEBROWSE, OnMovieFileBrowse )
DLG_ON_COMMAND( IDC_MCV_AVIBROWSE, OnAviFileBrowse )
DLG_ON_COMMAND( IDC_MCV_VIDEOSELECT, OnVideoCompressSelect )
DLG_ON_COMMAND( IDC_MCV_CONVERT, OnConvertStart )
DLG_COMMAND_END()
DLG_MESSAGE_END()
CAviConvDlg::CAviConvDlg() :
m_lpRender(NULL),
m_lpLinecolor(NULL),
m_lpScreen(NULL),
m_lpSound(NULL),
m_pNes(NULL),
m_hThread(NULL)
{
if( !(m_lpRender = (LPBYTE)::malloc( CDirectDraw::RENDER_WIDTH*CDirectDraw::RENDER_HEIGHT )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( !(m_lpScreen = (LPBYTE)::malloc( CDirectDraw::SCREEN_WIDTH*CDirectDraw::SCREEN_HEIGHT*3+16 )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( !(m_lpLinecolor = (LPBYTE)::malloc( CDirectDraw::RENDER_HEIGHT )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( !(m_lpSound = (LPBYTE)::malloc( 8192 )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
}
CAviConvDlg::~CAviConvDlg()
{
FREE( m_lpSound );
FREE( m_lpLinecolor );
FREE( m_lpScreen );
FREE( m_lpRender );
}
INT CAviConvDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_MOVIECONV),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CAviConvDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnInitDialog\n" );
m_szRomFile[0] = '\0';
m_szMovieFile[0] = '\0';
m_szAviFile[0] = '\0';
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_RESETCONTENT, 0, 0 );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)0, (LPARAM)"Full FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)1, (LPARAM)"1/2 FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)2, (LPARAM)"1/3 FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)3, (LPARAM)"1/4 FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)4, (LPARAM)"1/5 FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_INSERTSTRING, (WPARAM)5, (LPARAM)"1/6 FPS" );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_SETCURSEL, 0, 0 );
INT i, select = 0;
CHAR szMode[64];
::SendDlgItemMessage( m_hWnd, IDC_MCV_SAMPLERATE_COMBO, CB_RESETCONTENT, 0, 0 );
// for( i = 0; i < 8; i++ ) {
for( i = 0; CConfig::SamplingRateTable[i*2+0]; i++ ) {
::wsprintf( szMode, "%d.%03dKHz %2dbits",
CConfig::SamplingRateTable[i*2+0]/1000,
CConfig::SamplingRateTable[i*2+0]%1000,
CConfig::SamplingRateTable[i*2+1] );
::SendDlgItemMessage( m_hWnd, IDC_MCV_SAMPLERATE_COMBO, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szMode );
if( Config.sound.nRate == CConfig::SamplingRateTable[i*2+0]
&& Config.sound.nBits == CConfig::SamplingRateTable[i*2+1] ) {
select = i;
}
}
::SendDlgItemMessage( m_hWnd, IDC_MCV_FILTERTYPE_COMBO, CB_RESETCONTENT, 0, 0 );
for( i = IDS_SND_FILTER_NONE; i <= IDS_SND_FILTER_TYPE4; i++ ) {
CApp::LoadString( i, szMode, sizeof(szMode) );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FILTERTYPE_COMBO, CB_INSERTSTRING, (WPARAM)i-IDS_SND_FILTER_NONE, (LPARAM)szMode );
}
::SendDlgItemMessage( m_hWnd, IDC_MCV_SAMPLERATE_COMBO, CB_SETCURSEL, (WPARAM)select, 0 );
::SendDlgItemMessage( m_hWnd, IDC_MCV_FILTERTYPE_COMBO, CB_SETCURSEL, (WPARAM)Config.sound.nFilterType, 0 );
CTRLENABLE( IDC_MCV_CONVERT, FALSE );
ZEROMEMORY( &m_BitmapHdr, sizeof(m_BitmapHdr) );
m_BitmapHdr.biSize = sizeof(BITMAPINFOHEADER);
m_BitmapHdr.biWidth = 256;
m_BitmapHdr.biHeight = 240;
m_BitmapHdr.biPlanes = 1;
m_BitmapHdr.biBitCount = 24;
m_BitmapHdr.biCompression = BI_RGB;
m_BitmapHdr.biSizeImage = 256*240*3;
::GetWindowText( m_hWnd, m_szTitle, sizeof(m_szTitle)-1 );
m_AviWriter.SetVideoFormat( &m_BitmapHdr );
m_hThread = NULL;
return TRUE;
}
DLGCMD CAviConvDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnCancel\n" );
::KillTimer( m_hWnd, 0x1234 );
if( m_hThread ) {
m_bThreadExit = TRUE;
::WaitForSingleObject( m_hThread, INFINITE );
CLOSEHANDLE( m_hThread );
m_bThreadExit = FALSE;
if( m_pNes ) {
m_pNes->MovieStop();
DELETEPTR( m_pNes );
}
m_AviWriter.Close();
::SetWindowText( m_hWnd, m_szTitle );
ControlEnable( TRUE );
} else {
::EndDialog( m_hWnd, IDCANCEL );
}
}
DLGCMD CAviConvDlg::OnRomFileBrowse( DLGCMDPARAM )
{
string pathstr;
if( Config.path.bRomPath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szRomPath );
} else {
pathstr = CApp::GetModulePath();
}
::GetDlgItemText( m_hWnd, IDC_MCV_ROMFILE, m_szRomFile, sizeof(m_szRomFile)-1 );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_OPENROM, szTitle, sizeof(szTitle) );
OPENFILENAME ofn = { sizeof(OPENFILENAME) };
ofn.hwndOwner = m_hWnd;
ofn.lpstrFile = m_szRomFile;
ofn.nMaxFile = sizeof(m_szRomFile);
ofn.lpstrFilter = "All Support Types\0*.nes;*.fds;*.lzh;*.zip;*.rar;*.cab\0"
"NES ROM (*.nes)\0*.nes\0Disk Image (*.fds)\0*.fds\0"
"Archive File\0*.lzh;*.zip;*.rar;*.cab\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST;
ofn.lpstrInitialDir = pathstr.c_str();
ofn.lpstrTitle = szTitle;
if( ::GetOpenFileName( &ofn ) ) {
::SetDlgItemText( m_hWnd, IDC_MCV_ROMFILE, m_szRomFile );
}
}
DLGCMD CAviConvDlg::OnMovieFileBrowse( DLGCMDPARAM )
{
string pathstr;
if( Config.path.bMoviePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szMoviePath );
::CreateDirectory( pathstr.c_str(), NULL );
} else {
pathstr = CApp::GetModulePath();
}
::GetDlgItemText( m_hWnd, IDC_MCV_MOVIEFILE, m_szMovieFile, sizeof(m_szMovieFile)-1 );
OPENFILENAME ofn = { sizeof(OPENFILENAME) };
ofn.hwndOwner = m_hWnd;
ofn.lpstrFile = m_szMovieFile;
ofn.lpstrDefExt = "vmv";
ofn.nMaxFile = sizeof(m_szMovieFile);
ofn.lpstrFilter = "Movie Files(*.vmv)\0*.vmv\0All Files(*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST;
ofn.lpstrInitialDir = pathstr.c_str();
CHAR szTitle[256];
CApp::LoadString( IDS_UI_PLAYMOVIE, szTitle, sizeof(szTitle) );
ofn.lpstrTitle = szTitle;
if( ::GetOpenFileName( &ofn ) ) {
::SetDlgItemText( m_hWnd, IDC_MCV_MOVIEFILE, m_szMovieFile );
}
}
DLGCMD CAviConvDlg::OnAviFileBrowse( DLGCMDPARAM )
{
string pathstr, tempstr;
if( Config.path.bMoviePath ) {
pathstr = CPathlib::CreatePath( CApp::GetModulePath(), Config.path.szMoviePath );
::CreateDirectory( pathstr.c_str(), NULL );
} else {
pathstr = CApp::GetModulePath();
}
::GetDlgItemText( m_hWnd, IDC_MCV_AVIFILE, m_szAviFile, sizeof(m_szAviFile)-1 );
OPENFILENAME ofn = { sizeof(OPENFILENAME) };
ofn.hwndOwner = m_hWnd;
ofn.lpstrFile = m_szAviFile;
ofn.lpstrDefExt = "avi";
ofn.nMaxFile = sizeof(m_szAviFile);
ofn.lpstrFilter = "Movie Files(*.avi)\0*.avi\0All Files(*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT;
ofn.lpstrInitialDir = pathstr.c_str();
// CHAR szTitle[256];
// CApp::LoadString( IDS_UI_AVICONV, szTitle, sizeof(szTitle) );
// ofn.lpstrTitle = szTitle;
if( ::GetSaveFileName( &ofn ) ) {
::SetDlgItemText( m_hWnd, IDC_MCV_AVIFILE, m_szAviFile );
}
}
DLGCMD CAviConvDlg::OnVideoCompressSelect( DLGCMDPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnCompressSelect\n" );
if( !m_AviWriter.SelectVideoFormat( m_hWnd ) ) {
return;
}
CTRLENABLE( IDC_MCV_CONVERT, TRUE );
}
DLGMSG CAviConvDlg::OnConvertDone( DLGMSGPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnConvertDone\n" );
::KillTimer( m_hWnd, 0x1234 );
::WaitForSingleObject( m_hThread, INFINITE );
CLOSEHANDLE( m_hThread );
::SetWindowText( m_hWnd, m_szTitle );
m_AviWriter.Close();
DELETEPTR( m_pNes );
ControlEnable( TRUE );
CHAR szTemp[256];
DWORD totaltime = (m_FinishTime - m_StartTime) / 1000;
INT h, m, s;
h = totaltime / 3600;
totaltime %= 3600;
m = totaltime / 60;
s = totaltime % 60;
::wsprintf( szTemp, "Convert Finished. Time:%02d:%02d:%02d", h, m, s );
::MessageBox( m_hWnd, szTemp, "VirtuaNES", MB_OK );
return TRUE;
}
DLGMSG CAviConvDlg::OnConvertError( DLGMSGPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnConvertError\n" );
::KillTimer( m_hWnd, 0x1234 );
::WaitForSingleObject( m_hThread, INFINITE );
CLOSEHANDLE( m_hThread );
::SetWindowText( m_hWnd, m_szTitle );
m_AviWriter.Close();
DELETEPTR( m_pNes );
ControlEnable( TRUE );
::MessageBox( m_hWnd, (LPSTR)lParam, "VirtuaNES", MB_OK );
return TRUE;
}
DLGCMD CAviConvDlg::OnConvertStart( DLGCMDPARAM )
{
// DEBUGOUT( "CAviConvDlg::OnConvertStart\n" );
::GetDlgItemText( m_hWnd, IDC_MCV_ROMFILE, m_szRomFile, sizeof(m_szRomFile)-1 );
::GetDlgItemText( m_hWnd, IDC_MCV_MOVIEFILE, m_szMovieFile, sizeof(m_szMovieFile)-1 );
::GetDlgItemText( m_hWnd, IDC_MCV_AVIFILE, m_szAviFile, sizeof(m_szAviFile)-1 );
INT select;
select = ::SendDlgItemMessage( m_hWnd, IDC_MCV_FRAMERATE_COMBO, CB_GETCURSEL, 0, 0 );
#if 1
m_FrameDivider = select + 1;
#else
switch( select ) {
default:
case 0: m_FrameDivider = 1; break;
case 1: m_FrameDivider = 2; break;
case 2: m_FrameDivider = 3; break;
case 3: m_FrameDivider = 4; break;
case 4: m_FrameDivider = 5; break;
case 5: m_FrameDivider = 6; break;
}
#endif
select = ::SendDlgItemMessage( m_hWnd, IDC_MCV_SAMPLERATE_COMBO, CB_GETCURSEL, 0, 0 );
Config.sound.nRate = CConfig::SamplingRateTable[select*2+0];
Config.sound.nBits = CConfig::SamplingRateTable[select*2+1];
Config.sound.nFilterType = ::SendDlgItemMessage( m_hWnd, IDC_MCV_FILTERTYPE_COMBO, CB_GETCURSEL, 0, 0 );
m_AviWriter.SetAudioFormat( Config.sound.nRate, Config.sound.nBits, 1 );
m_hThread = NULL;
try {
m_pNes = new NES(m_szRomFile);
m_pNes->ppu->SetScreenPtr( m_lpRender, m_lpLinecolor );
m_pNes->Reset();
if( !m_pNes->MoviePlay( m_szMovieFile ) )
throw "MoviePlay error.";
WORD wRecVersion, wVersion;
DWORD dwRecordTimes;
m_pNes->GetMovieInfo( wRecVersion, wVersion, m_RecordFrames, dwRecordTimes );
m_AviWriter.SetFrameRate( 10000, m_pNes->nescfg->FrameRate * 10000 / m_FrameDivider );
if( !m_AviWriter.Open( m_szAviFile ) ) {
CHAR szTemp[256];
::wsprintf( szTemp, CApp::GetErrorString(IDS_ERROR_OPEN), m_szAviFile );
throw szTemp;
}
if( !(m_hThread = ::CreateThread( NULL, 0, ThreadProc, this, CREATE_SUSPENDED, &m_dwThreadID )) ) {
throw "CreateThread failed.";
}
ControlEnable( FALSE );
DirectDraw.GetPaletteData2( m_Palette );
m_FrameNo = -1;
// Time Remain
::SetTimer( m_hWnd, 0x1234, 500, NULL );
// start converter
m_bThreadExit = FALSE;
// m_StartTime = m_FinishTime = ::timeGetTime();
::ResumeThread( m_hThread );
} catch( CHAR* str ) {
if( m_hThread ) {
::TerminateThread( m_hThread, 0 );
CLOSEHANDLE( m_hThread );
}
::KillTimer( m_hWnd, 0x1234 );
m_AviWriter.Close();
DELETEPTR( m_pNes );
::MessageBox( m_hWnd, str, "VirtuaNES", MB_OK );
#ifndef _DEBUG
} catch(...) {
if( m_hThread ) {
::TerminateThread( m_hThread, 0 );
CLOSEHANDLE( m_hThread );
}
::KillTimer( m_hWnd, 0x1234 );
m_AviWriter.Close();
DELETEPTR( m_pNes );
::MessageBox( m_hWnd, CApp::GetErrorString( IDS_ERROR_UNKNOWN ), "VirtuaNES", MB_OK );
#endif
}
}
DLGMSG CAviConvDlg::OnTimer( DLGMSGPARAM )
{
CHAR szTemp[256];
INT nowframe = m_FrameNo;
DWORD elapsed = ::timeGetTime() - m_StartTime;
if( m_FrameNo >= 0 && elapsed > 5000 ) {
DWORD elapsedave = elapsed / nowframe;
DWORD estimation = elapsedave * (m_RecordFrames-nowframe) / 1000;
INT h, m, s;
h = estimation / 3600;
estimation %= 3600;
m = estimation / 60;
s = estimation % 60;
::wsprintf( szTemp, "%s [%d/%d] Time remain %02d:%02d:%02d", m_szTitle, m_FrameNo, m_RecordFrames, h, m, s );
} else {
::wsprintf( szTemp, "%s [%d/%d] Time remain --:--:--", m_szTitle, m_FrameNo, m_RecordFrames );
}
::SetWindowText( m_hWnd, szTemp );
return FALSE;
}
DWORD WINAPI CAviConvDlg::ThreadProc( LPVOID lpVoid )
{
CAviConvDlg* pAviConvDlg = (CAviConvDlg*)lpVoid;
NES* pNes = pAviConvDlg->m_pNes;
CAVIWriter& AviWriter = pAviConvDlg->m_AviWriter;
LPBYTE pRender = pAviConvDlg->m_lpRender;
LPBYTE pScreen = pAviConvDlg->m_lpScreen;
LPBYTE pLinecolor = pAviConvDlg->m_lpLinecolor;
RGBQUAD* pPalette = pAviConvDlg->m_Palette;
LPBYTE pSound = pAviConvDlg->m_lpSound;
INT FrameDivider = pAviConvDlg->m_FrameDivider;
BOOL bFinish = FALSE;
double Samples = 0.0;
pAviConvDlg->m_FrameNo = 0;
pAviConvDlg->m_StartTime = pAviConvDlg->m_FinishTime = ::timeGetTime();
while( !pAviConvDlg->m_bThreadExit ) {
if( !pNes->IsMoviePlay() ) {
bFinish = TRUE;
break;
}
try {
pNes->Movie();
if( (pAviConvDlg->m_FrameNo % FrameDivider) == 0 ) {
pNes->EmulateFrame( TRUE );
for( INT i = 0; i < CDirectDraw::SCREEN_HEIGHT; i++ ) {
LPBYTE pSrc = &pRender[CDirectDraw::RENDER_WIDTH*i+8];
LPBYTE pDst = &pScreen[CDirectDraw::SCREEN_WIDTH*3*(CDirectDraw::SCREEN_HEIGHT-i-1)];
RGBQUAD* pPal = &pPalette[ (pLinecolor[i] & 7)*256+((pLinecolor[i] & 0x80)?0x40:0x00) ];
#if 0
for( INT j = 0; j < CDirectDraw::SCREEN_WIDTH; j++ ) {
BYTE pixel = *pSrc++;
pixel |= (pLinecolor[i] & 0x80)?0x40:0;
*pDst++ = pPal[ pixel ].rgbBlue;
*pDst++ = pPal[ pixel ].rgbGreen;
*pDst++ = pPal[ pixel ].rgbRed;
}
#else
DWORD width = CDirectDraw::SCREEN_WIDTH;
__asm {
mov eax, pSrc
mov esi, pPal
mov edi, pDst
_render_loop:
mov edx, [eax]
movzx ebx, dl
mov ebx, [esi+ebx*4]
shr edx, 8
mov [edi+ 0], ebx
movzx ebx, dl
mov ebx, [esi+ebx*4]
shr edx, 8
mov [edi+ 3], ebx
movzx ebx, dl
shr edx, 8
mov ebx, [esi+ebx*4]
mov edx, [esi+edx*4]
mov [edi+ 6], ebx
mov [edi+ 9], dx
shr edx, 16
mov [edi+11], dl
mov edx, [eax+4]
movzx ebx, dl
mov ebx, [esi+ebx*4]
shr edx, 8
mov [edi+12], ebx
movzx ebx, dl
mov ebx, [esi+ebx*4]
shr edx, 8
mov [edi+15], ebx
movzx ebx, dl
shr edx, 8
mov ebx, [esi+ebx*4]
mov edx, [esi+edx*4]
mov [edi+18], ebx
mov [edi+21], dx
shr edx, 16
mov [edi+23], dl
lea eax, [eax+ 8]
lea edi, [edi+24]
sub width, 8
jg _render_loop
}
#endif
}
if( !AviWriter.WriteVideo( (const char*)pScreen ) ) {
throw "Write error.(video)";
}
} else {
pNes->EmulateFrame( FALSE );
}
INT size;
INT blockalign = Config.sound.nBits / 8;
Samples += ((double)Config.sound.nRate / (double)pNes->nescfg->FrameRate) * (double)blockalign;
size = (INT)Samples - ((INT)Samples % blockalign);
Samples -= size;
pNes->apu->Process( pSound, size );
if( !AviWriter.WriteAudio( (const char*)pSound, size ) ) {
throw "Write error.(audio)";
}
pAviConvDlg->m_FrameNo++;
} catch( CHAR* str ) {
pNes->MovieStop();
AviWriter.Close();
::strcpy( g_szErrorMessage, str );
::PostMessage( pAviConvDlg->m_hWnd, WM_APP+101, 0, (LPARAM)g_szErrorMessage );
pAviConvDlg->m_bThreadExit = TRUE;
#ifndef _DEBUG
} catch(...) {
pNes->MovieStop();
AviWriter.Close();
::PostMessage( pAviConvDlg->m_hWnd, WM_APP+101, 0, (LPARAM)CApp::GetErrorString( IDS_ERROR_UNKNOWN ) );
pAviConvDlg->m_bThreadExit = TRUE;
#endif
}
// For Windows9x
::Sleep( 0 );
}
pNes->MovieStop();
AviWriter.Close();
if( bFinish ) {
pAviConvDlg->m_FinishTime = ::timeGetTime();
// Convert Done
::PostMessage( pAviConvDlg->m_hWnd, WM_APP+100, 0, 0 );
}
return 0;
}
void CAviConvDlg::ControlEnable( BOOL bEnable )
{
CTRLENABLE( IDC_MCV_ROMBROWSE, bEnable );
CTRLENABLE( IDC_MCV_MOVIEBROWSE, bEnable );
CTRLENABLE( IDC_MCV_AVIBROWSE, bEnable );
CTRLENABLE( IDC_MCV_ROMFILE, bEnable );
CTRLENABLE( IDC_MCV_MOVIEFILE, bEnable );
CTRLENABLE( IDC_MCV_AVIFILE, bEnable );
CTRLENABLE( IDC_MCV_FRAMERATE_COMBO, bEnable );
CTRLENABLE( IDC_MCV_SAMPLERATE_COMBO, bEnable );
CTRLENABLE( IDC_MCV_FILTERTYPE_COMBO, bEnable );
CTRLENABLE( IDC_MCV_VIDEOSELECT, bEnable );
CTRLENABLE( IDC_MCV_CONVERT, bEnable );
}