diff --git a/doc/todo.txt b/doc/todo.txt index 6fd2a2bd..d09ac777 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -20,12 +20,13 @@ Important: Less important: +- Add GBA cheat editing support (GB already has) + - Look at Cheats.cpp (Core) and GBACheats.cpp (GUI) + - Support D3DFMT_A2R10G10B10 (10 bit per color component) color format - Add documentation for VBA-M (configuration guide) -- DDraw, D3D, OGL: Add full screen device & frequency selection - - Improve AVI recording (produces asynchronous files) - Enable audio stream compression for AVI files diff --git a/src/win32/FullscreenSettings.cpp b/src/win32/FullscreenSettings.cpp index 41d5d3b1..25792fea 100644 --- a/src/win32/FullscreenSettings.cpp +++ b/src/win32/FullscreenSettings.cpp @@ -100,12 +100,23 @@ BOOL FullscreenSettings::OnInitDialog() } #endif -//#ifndef NO_OGL - //case OPENGL: - //break; -//#endif - - // TODO: Add extra initialization here +#ifndef NO_OGL + if( api == OPENGL ) { + // enumerate devices + DWORD iDevice = 0; + DISPLAY_DEVICE devInfo; + ZeroMemory( &devInfo, sizeof(devInfo) ); + devInfo.cb = sizeof(devInfo); + combo_device.ResetContent(); + while( TRUE == EnumDisplayDevices( NULL, iDevice, &devInfo, 0 ) ) { + int index = combo_device.AddString( devInfo.DeviceString ); + combo_device.SetItemData( index, (DWORD_PTR)iDevice ); + iDevice++; + } + combo_device.SetCurSel( 0 ); + OnCbnSelchangeComboDevice(); + } +#endif return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE @@ -121,7 +132,7 @@ void FullscreenSettings::setAPI( DISPLAY_TYPE type ) void FullscreenSettings::OnCbnSelchangeComboDevice() { - if( failed ) return; + failed = false; #ifndef NO_D3D if( api == DIRECT_3D ) { @@ -162,10 +173,66 @@ void FullscreenSettings::OnCbnSelchangeComboDevice() if( combo_color_depth.GetCount() == 0 ) { failed = true; + combo_resolution.ResetContent(); + combo_refresh_rate.ResetContent(); return; } - combo_color_depth.SetCurSel( 0 ); + combo_color_depth.SetCurSel( combo_color_depth.GetCount() - 1 ); + OnCbnSelchangeComboColorDepth(); + } +#endif + +#ifndef NO_OGL + if( api == OPENGL ) { + int selection; + + // get selected device's name + selection = combo_device.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD iDevice = (UINT)combo_device.GetItemData( selection ); + DISPLAY_DEVICE devInfo; + ZeroMemory( &devInfo, sizeof(devInfo) ); + devInfo.cb = sizeof(devInfo); + EnumDisplayDevices( NULL, iDevice, &devInfo, 0 ); + + // enumerate color depths + DWORD iMode = 0; + DEVMODE mode; + ZeroMemory( &mode, sizeof(mode) ); + mode.dmSize = sizeof(mode); + bool alreadyExists; + combo_color_depth.ResetContent(); + + while( TRUE == EnumDisplaySettings( devInfo.DeviceName, iMode, &mode ) ) { + if( mode.dmDisplayFlags != 0 ) { + iMode++; + continue; // don't list special modes + } + alreadyExists = false; + for( int iItem = 0 ; iItem < combo_color_depth.GetCount() ; iItem++ ) { + if( mode.dmBitsPerPel == (DWORD)combo_color_depth.GetItemData( iItem ) ) { + alreadyExists = true; + break; + } + } + if( !alreadyExists ) { + CString temp; + temp.Format( _T("%2u bits per pixel"), mode.dmBitsPerPel ); + int index = combo_color_depth.AddString( temp ); + combo_color_depth.SetItemData( index, (DWORD_PTR)mode.dmBitsPerPel ); + } + iMode++; + } + + if( combo_color_depth.GetCount() == 0 ) { + failed = true; + combo_resolution.ResetContent(); + combo_refresh_rate.ResetContent(); + return; + } + + combo_color_depth.SetCurSel( combo_color_depth.GetCount() - 1 ); OnCbnSelchangeComboColorDepth(); } #endif @@ -217,14 +284,73 @@ void FullscreenSettings::OnCbnSelchangeComboColorDepth() allModes[i] = mode; } } - delete [] allModes; - - int count = combo_resolution.GetCount(); - combo_resolution.SetCurSel( count - 1 ); // select last item - OnCbnSelchangeComboResolution(); } #endif + +#ifndef NO_OGL + if( api == OPENGL ) { + int selection; + + // get selected device's name + selection = combo_device.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD iDevice = (UINT)combo_device.GetItemData( selection ); + DISPLAY_DEVICE devInfo; + ZeroMemory( &devInfo, sizeof(devInfo) ); + devInfo.cb = sizeof(devInfo); + EnumDisplayDevices( NULL, iDevice, &devInfo, 0 ); + + // get selected bit depth value + selection = combo_color_depth.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD selectedBPP = (DWORD)combo_color_depth.GetItemData( selection ); + + + // enumerate resolutions + DWORD iMode = 0; + DEVMODE mode, surfMode; + ZeroMemory( &mode, sizeof(mode) ); + ZeroMemory( &surfMode, sizeof(surfMode) ); + mode.dmSize = sizeof(mode); + surfMode.dmSize = sizeof(surfMode); + bool alreadyExists; + combo_resolution.ResetContent(); + + while( TRUE == EnumDisplaySettings( devInfo.DeviceName, iMode, &mode ) ) { + if( ( mode.dmBitsPerPel != selectedBPP) || + ( mode.dmDisplayFlags != 0 ) ) { + iMode++; + continue; + } + alreadyExists = false; + for( int iItem = 0 ; iItem < combo_resolution.GetCount() ; iItem++ ) { + DWORD iSurfMode = (DWORD)combo_resolution.GetItemData( iItem ); + EnumDisplaySettings( devInfo.DeviceName, iSurfMode, &surfMode ); + if( ( mode.dmPelsWidth == surfMode.dmPelsWidth ) && + ( mode.dmPelsHeight == surfMode.dmPelsHeight ) ) { + alreadyExists = true; + break; + } + } + if( !alreadyExists ) { + CString temp; + temp.Format( _T("%4u x %4u"), mode.dmPelsWidth, mode.dmPelsHeight ); + int index = combo_resolution.AddString( temp ); + combo_resolution.SetItemData( index, (DWORD_PTR)iMode ); + } + iMode++; + } + + if( combo_resolution.GetCount() == 0 ) { + failed = true; + return; + } + } +#endif + + combo_resolution.SetCurSel( combo_resolution.GetCount() - 1 ); // select last item + OnCbnSelchangeComboResolution(); } @@ -267,11 +393,72 @@ void FullscreenSettings::OnCbnSelchangeComboResolution() combo_refresh_rate.SetItemData( index, (DWORD_PTR)i ); } } - - int count = combo_refresh_rate.GetCount(); - combo_refresh_rate.SetCurSel( count - 1 ); // select last item } #endif + +#ifndef NO_OGL + if( api == OPENGL ) { + int selection; + + // get selected device's name + selection = combo_device.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD iDevice = (UINT)combo_device.GetItemData( selection ); + DISPLAY_DEVICE devInfo; + ZeroMemory( &devInfo, sizeof(devInfo) ); + devInfo.cb = sizeof(devInfo); + EnumDisplayDevices( NULL, iDevice, &devInfo, 0 ); + + // get selected resolution / bpp + DEVMODE selectedResolution; + ZeroMemory( &selectedResolution, sizeof(selectedResolution) ); + selectedResolution.dmSize = sizeof(selectedResolution); + selection = combo_resolution.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD dwSelectedRes = (DWORD)combo_resolution.GetItemData( selection ); + EnumDisplaySettings( devInfo.DeviceName, dwSelectedRes, &selectedResolution ); + + + // enumerate refresh rates + DWORD iMode = 0; + DEVMODE mode, surfMode; + ZeroMemory( &mode, sizeof(mode) ); + ZeroMemory( &surfMode, sizeof(surfMode) ); + mode.dmSize = sizeof(mode); + surfMode.dmSize = sizeof(surfMode); + bool alreadyExists; + combo_refresh_rate.ResetContent(); + + while( TRUE == EnumDisplaySettings( devInfo.DeviceName, iMode, &mode ) ) { + if( ( mode.dmBitsPerPel != selectedResolution.dmBitsPerPel ) || + ( mode.dmDisplayFlags != 0 ) || + ( mode.dmPelsWidth != selectedResolution.dmPelsWidth ) || + ( mode.dmPelsHeight != selectedResolution.dmPelsHeight ) ) { + iMode++; + continue; + } + alreadyExists = false; + for( int iItem = 0 ; iItem < combo_refresh_rate.GetCount() ; iItem++ ) { + DWORD iSurfMode = (DWORD)combo_refresh_rate.GetItemData( iItem ); + EnumDisplaySettings( devInfo.DeviceName, iSurfMode, &surfMode ); + if( ( mode.dmDisplayFrequency == surfMode.dmDisplayFrequency ) ) { + alreadyExists = true; + break; + } + } + if( !alreadyExists ) { + CString temp; + temp.Format( _T("%3u Hz"), mode.dmDisplayFrequency ); + int index = combo_refresh_rate.AddString( temp ); + combo_refresh_rate.SetItemData( index, (DWORD_PTR)iMode ); + } + iMode++; + } + + } +#endif + + combo_refresh_rate.SetCurSel( combo_refresh_rate.GetCount() - 1 ); // select last item } void FullscreenSettings::OnOK() @@ -279,42 +466,90 @@ void FullscreenSettings::OnOK() if( failed ) return; #ifndef NO_D3D - int selection; + if( api == DIRECT_3D ) { + int selection; - selection = combo_device.GetCurSel(); - if( selection == LB_ERR ) return; - UINT adapter = (UINT)combo_device.GetItemData( selection ); + selection = combo_device.GetCurSel(); + if( selection == LB_ERR ) return; + UINT adapter = (UINT)combo_device.GetItemData( selection ); - selection = combo_color_depth.GetCurSel(); - if( selection == LB_ERR ) return; - D3DFORMAT format = (D3DFORMAT)combo_color_depth.GetItemData( selection ); + selection = combo_color_depth.GetCurSel(); + if( selection == LB_ERR ) return; + D3DFORMAT format = (D3DFORMAT)combo_color_depth.GetItemData( selection ); - selection = combo_refresh_rate.GetCurSel(); - if( selection == LB_ERR ) return; - UINT selectedMode = (UINT)combo_refresh_rate.GetItemData( selection ); + selection = combo_refresh_rate.GetCurSel(); + if( selection == LB_ERR ) return; + UINT selectedMode = (UINT)combo_refresh_rate.GetItemData( selection ); - D3DDISPLAYMODE mode; - pD3D->EnumAdapterModes( adapter, format, selectedMode, &mode ); + D3DDISPLAYMODE mode; + pD3D->EnumAdapterModes( adapter, format, selectedMode, &mode ); - m_device = (unsigned int)adapter; - switch( mode.Format ) - { // TODO: use these assignments for VBA as well - case D3DFMT_A2R10G10B10: - m_colorDepth = 30; - break; - case D3DFMT_X8R8G8B8: - m_colorDepth = 24; - break; - case D3DFMT_R5G6B5: - m_colorDepth = 16; - break; - case D3DFMT_X1R5G5B5: - m_colorDepth = 15; - break; + m_device = (unsigned int)adapter; + switch( mode.Format ) + { // TODO: use these assignments for VBA as well + case D3DFMT_A2R10G10B10: + m_colorDepth = 30; + break; + case D3DFMT_X8R8G8B8: + m_colorDepth = 24; + break; + case D3DFMT_R5G6B5: + m_colorDepth = 16; + break; + case D3DFMT_X1R5G5B5: + m_colorDepth = 15; + break; + } + m_width = (unsigned int)mode.Width; + m_height = (unsigned int)mode.Height; + m_refreshRate = (unsigned int)mode.RefreshRate; + } +#endif + +#ifndef NO_OGL + if( api == OPENGL ) { + int selection; + + // get selected device's name + selection = combo_device.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD iDevice = (UINT)combo_device.GetItemData( selection ); + DISPLAY_DEVICE devInfo; + ZeroMemory( &devInfo, sizeof(devInfo) ); + devInfo.cb = sizeof(devInfo); + EnumDisplayDevices( NULL, iDevice, &devInfo, 0 ); + + // get selected resolution / bpp + DEVMODE mode; + ZeroMemory( &mode, sizeof(mode) ); + mode.dmSize = sizeof(mode); + selection = combo_refresh_rate.GetCurSel(); + if( selection == LB_ERR ) return; + DWORD selectedMode = (DWORD)combo_refresh_rate.GetItemData( selection ); + EnumDisplaySettings( devInfo.DeviceName, selectedMode, &mode ); + + + m_device = (unsigned int)iDevice; + switch( mode.dmBitsPerPel ) + { // the policy of this dialog is to return the actually usable amount of bits + case 4: + m_colorDepth = 4; + break; + case 8: + m_colorDepth = 8; + break; + case 16: + m_colorDepth = 16; + break; + case 24: + case 32: + m_colorDepth = 24; + break; + } + m_width = (unsigned int)mode.dmPelsWidth; + m_height = (unsigned int)mode.dmPelsHeight; + m_refreshRate = (unsigned int)mode.dmDisplayFrequency; } - m_width = (unsigned int)mode.Width; - m_height = (unsigned int)mode.Height; - m_refreshRate = (unsigned int)mode.RefreshRate; #endif CDialog::OnOK(); diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc index 0a98daa5..12140a17 100644 --- a/src/win32/VBA.rc +++ b/src/win32/VBA.rc @@ -1139,7 +1139,7 @@ BEGIN COMBOBOX IDC_COMBO_RESOLUTION,60,42,102,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP RTEXT "Resolution:",IDC_STATIC,6,42,48,12 RTEXT "Color depth:",IDC_STATIC,6,24,48,12 - COMBOBOX IDC_COMBO_COLOR_DEPTH,60,24,102,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_COLOR_DEPTH,60,24,102,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP RTEXT "Refresh rate:",IDC_STATIC,6,60,48,12 COMBOBOX IDC_COMBO_REFRESH_RATE,60,60,102,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_DEVICE,60,6,102,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP