diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 1018b702b9..40dc665655 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -242,6 +242,7 @@ public: ScopedPtr ToolbarImages; ScopedPtr IconBundle; ScopedPtr Bitmap_Logo; + ScopedPtr ScreenshotBitmap; ScopedPtr GameDB; pxAppResources(); @@ -559,6 +560,7 @@ public: pxAppResources& GetResourceCache(); const wxIconBundle& GetIconBundle(); const wxBitmap& GetLogoBitmap(); + const wxBitmap& GetScreenshotBitmap(); wxImageList& GetImgList_Config(); wxImageList& GetImgList_Toolbars(); diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index 8d0d6f60b7..7621378bb6 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -21,8 +21,11 @@ #include #include +#include "MSWstuff.h" + #include "Resources/EmbeddedImage.h" #include "Resources/BackgroundLogo.h" +#include "Resources/ButtonIcon_Camera.h" #include "Resources/ConfigIcon_Cpu.h" #include "Resources/ConfigIcon_Video.h" @@ -144,17 +147,42 @@ const wxBitmap& Pcsx2App::GetLogoBitmap() wxImage img; EmbeddedImage temp; // because gcc can't allow non-const temporaries. LoadImageAny( img, useTheme, mess, L"BackgroundLogo", temp ); - logo = new wxBitmap( img ); + float scale = MSW_GetDPIScale(); // 1.0 for non-Windows + logo = new wxBitmap(img.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_HIGH)); return *logo; } +const wxBitmap& Pcsx2App::GetScreenshotBitmap() +{ + ScopedPtr& screenshot(GetResourceCache().ScreenshotBitmap); + if (screenshot) return *screenshot; + + wxFileName mess; + bool useTheme = (g_Conf->DeskTheme != L"default"); + + if (useTheme) + { + wxDirName theme(PathDefs::GetThemes() + g_Conf->DeskTheme); + mess = theme.ToString(); + } + + wxImage img; + EmbeddedImage temp; // because gcc can't allow non-const temporaries. + LoadImageAny(img, useTheme, mess, L"ButtonIcon_Camera", temp); + float scale = MSW_GetDPIScale(); // 1.0 for non-Windows + screenshot = new wxBitmap(img.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_HIGH)); + + return *screenshot; +} + wxImageList& Pcsx2App::GetImgList_Config() { ScopedPtr& images( GetResourceCache().ConfigImages ); if( !images ) { - images = new wxImageList(32, 32); + int image_size = MSW_GetDPIScale() * g_Conf->Listbook_ImageSize; + images = new wxImageList(image_size, image_size); wxFileName mess; bool useTheme = (g_Conf->DeskTheme != L"default"); @@ -168,14 +196,19 @@ wxImageList& Pcsx2App::GetImgList_Config() // GCC Specific: wxT() macro is required when using string token pasting. For some // reason L generates syntax errors. >_< + // TODO: This can be fixed with something like + // #define L_STR(x) L_STR2(x) + // #define L_STR2(x) L ## x + // but it's probably best to do it everywhere at once. wxWidgets + // recommends not to use it since v2.9.0. #undef FancyLoadMacro #define FancyLoadMacro( name ) \ { \ - EmbeddedImage temp( g_Conf->Listbook_ImageSize, g_Conf->Listbook_ImageSize ); \ - m_Resources->ImageId.Config.name = images->Add( LoadImageAny( \ - img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp ) \ - ); \ + EmbeddedImage temp; \ + LoadImageAny(img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp); \ + img.Rescale(image_size, image_size, wxIMAGE_QUALITY_HIGH); \ + m_Resources->ImageId.Config.name = images->Add(img); \ } FancyLoadMacro( Paths ); @@ -190,6 +223,7 @@ wxImageList& Pcsx2App::GetImgList_Config() return *images; } +// This stuff seems unused? wxImageList& Pcsx2App::GetImgList_Toolbars() { ScopedPtr& images( GetResourceCache().ToolbarImages ); diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp index 96b3e336e0..962015dd71 100644 --- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp +++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp @@ -22,9 +22,6 @@ #include "ModalPopups.h" #include "Panels/ConfigurationPanels.h" -#include "Resources/EmbeddedImage.h" -#include "Resources/ButtonIcon_Camera.h" - #include #include #include @@ -187,7 +184,7 @@ void Dialogs::BaseConfigurationDialog::AddOkCancel( wxSizer* sizer ) if( wxWindow* apply = FindWindow( wxID_APPLY ) ) apply->Disable(); SomethingChanged_StateModified_IsChanged(); - wxBitmapButton& screenshotButton( *new wxBitmapButton( this, wxID_SAVE, EmbeddedImage().Get() ) ); + wxBitmapButton& screenshotButton(*new wxBitmapButton(this, wxID_SAVE, wxGetApp().GetScreenshotBitmap())); screenshotButton.SetToolTip( _("Saves a snapshot of this settings panel to a PNG file.") ); *m_extraButtonSizer += screenshotButton|pxMiddle; diff --git a/pcsx2/gui/MSWstuff.cpp b/pcsx2/gui/MSWstuff.cpp index 2ac3fca86c..cb80736c78 100644 --- a/pcsx2/gui/MSWstuff.cpp +++ b/pcsx2/gui/MSWstuff.cpp @@ -28,11 +28,13 @@ void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter ) #endif } +// Text scales automatically on Windows but that's about it. The dialog widths +// and images need to be scaled manually. float MSW_GetDPIScale() { #ifdef __WXMSW__ HDC screen = GetDC(0); - float scale = GetDeviceCaps(screen, LOGPIXELSX) / 96.0; + float scale = GetDeviceCaps(screen, LOGPIXELSX) / 96.0; // 96.0 dpi = 100% scale ReleaseDC(NULL, screen); return scale; diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index d1bfdbb429..41f38e9c9c 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -348,7 +348,9 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) // ------------------------------------------------------------------------ - wxSize backsize( m_background.GetSize() ); + // The background logo and its window size are different on Windows. Use the + // background logo size, which is what it'll eventually be resized to. + wxSize backsize(m_background.GetBitmap().GetWidth(), m_background.GetBitmap().GetHeight()); wxString wintitle; if( PCSX2_isReleaseVersion ) @@ -385,6 +387,10 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) wxBoxSizer& joe( *new wxBoxSizer( wxVERTICAL ) ); joe.Add( &m_background ); SetSizerAndFit( &joe ); + // Makes no sense, but this is needed for the window size to be correct for + // 200% DPI on Windows. The SetSizerAndFit is supposed to be doing the exact + // same thing. + GetSizer()->SetSizeHints(this); // Use default window position if the configured windowpos is invalid (partially offscreen) if( g_Conf->MainGuiPosition == wxDefaultPosition || !pxIsValidWindowPosition( *this, g_Conf->MainGuiPosition) ) diff --git a/pcsx2/gui/Resources/EmbeddedImage.h b/pcsx2/gui/Resources/EmbeddedImage.h index b68199802d..91051ecd08 100644 --- a/pcsx2/gui/Resources/EmbeddedImage.h +++ b/pcsx2/gui/Resources/EmbeddedImage.h @@ -26,8 +26,7 @@ class IEmbeddedImage { public: virtual const wxImage& Get()=0; - virtual wxImage Rescale( int width, int height )=0; - virtual wxImage Resample( int width, int height )=0; + virtual wxImage Scale( int width, int height )=0; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -59,7 +58,7 @@ protected: m_Image.LoadFile( joe, ImageType::GetFormat() ); if( m_ResampleTo.IsFullySpecified() && ( m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight() ) ) - m_Image = m_Image.ResampleBox( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight() ); + m_Image.Rescale( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH ); } } @@ -107,31 +106,15 @@ public: // ------------------------------------------------------------------------ // Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage - // is left unmodified). Useful for creating ugly versions of otherwise nice graphics. Do - // us all a favor and use Resample() instead. + // is left unmodified). // - // (this method included for sake of completeness only). - // - wxImage Rescale( int width, int height ) - { - _loadImage(); - if( width != m_Image.GetWidth() || height != m_Image.GetHeight() ) - return m_Image.Rescale( width, height ); - else - return m_Image; - } - // ------------------------------------------------------------------------ - // Implementation Note: This function uses wxWidgets ResampleBox method to resize the image. - // wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down- - // sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner - // results. - // - wxImage Resample( int width, int height ) + wxImage Scale( int width, int height ) { _loadImage(); + // Not strictly necessary - wxWidgets does the dimensions check anyway. if( width != m_Image.GetWidth() || height != m_Image.GetHeight() ) - return m_Image.ResampleBox( width, height ); + return m_Image.Scale( width, height, wxIMAGE_QUALITY_HIGH ); else return m_Image; }