mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-10 14:39:01 +01:00
2x banner images!
This commit is contained in:
parent
0787019cbe
commit
18abc33306
@ -1,3 +1,4 @@
|
|||||||
|
// XXX comex: scale support
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: src/generic/treectlg.cpp
|
// Name: src/generic/treectlg.cpp
|
||||||
// Purpose: generic tree control implementation
|
// Purpose: generic tree control implementation
|
||||||
|
14
Externals/wxWidgets3/src/osx/imaglist.cpp
vendored
14
Externals/wxWidgets3/src/osx/imaglist.cpp
vendored
@ -73,16 +73,16 @@ int wxImageList::Add( const wxIcon &bitmap )
|
|||||||
|
|
||||||
int wxImageList::Add( const wxBitmap &bitmap )
|
int wxImageList::Add( const wxBitmap &bitmap )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( (bitmap.GetWidth() >= m_width && bitmap.GetHeight() == m_height)
|
wxASSERT_MSG( (bitmap.GetScaledWidth() >= m_width && bitmap.GetScaledHeight() == m_height)
|
||||||
|| (m_width == 0 && m_height == 0),
|
|| (m_width == 0 && m_height == 0),
|
||||||
wxT("invalid bitmap size in wxImageList: this might work ")
|
wxT("invalid bitmap size in wxImageList: this might work ")
|
||||||
wxT("on this platform but definitely won't under Windows.") );
|
wxT("on this platform but definitely won't under Windows.") );
|
||||||
|
|
||||||
// Mimic behaviour of Windows ImageList_Add that automatically breaks up the added
|
// Mimic behaviour of Windows ImageList_Add that automatically breaks up the added
|
||||||
// bitmap into sub-images of the correct size
|
// bitmap into sub-images of the correct size
|
||||||
if (m_width > 0 && bitmap.GetWidth() > m_width && bitmap.GetHeight() >= m_height)
|
if (m_width > 0 && bitmap.GetScaledWidth() > m_width && bitmap.GetScaledHeight() >= m_height)
|
||||||
{
|
{
|
||||||
int numImages = bitmap.GetWidth() / m_width;
|
int numImages = bitmap.GetScaledWidth() / m_width;
|
||||||
for (int subIndex = 0; subIndex < numImages; subIndex++)
|
for (int subIndex = 0; subIndex < numImages; subIndex++)
|
||||||
{
|
{
|
||||||
wxRect rect(m_width * subIndex, 0, m_width, m_height);
|
wxRect rect(m_width * subIndex, 0, m_width, m_height);
|
||||||
@ -97,8 +97,8 @@ int wxImageList::Add( const wxBitmap &bitmap )
|
|||||||
|
|
||||||
if (m_width == 0 && m_height == 0)
|
if (m_width == 0 && m_height == 0)
|
||||||
{
|
{
|
||||||
m_width = bitmap.GetWidth();
|
m_width = bitmap.GetScaledWidth();
|
||||||
m_height = bitmap.GetHeight();
|
m_height = bitmap.GetScaledHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_images.GetCount() - 1;
|
return m_images.GetCount() - 1;
|
||||||
@ -275,8 +275,8 @@ bool wxImageList::GetSize( int index, int &width, int &height ) const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxBitmap *bm = static_cast< wxBitmap* >(obj ) ;
|
wxBitmap *bm = static_cast< wxBitmap* >(obj ) ;
|
||||||
width = bm->GetWidth();
|
width = bm->GetScaledWidth();
|
||||||
height = bm->GetHeight();
|
height = bm->GetScaledHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -26,7 +26,7 @@ class IBannerLoader
|
|||||||
|
|
||||||
virtual bool IsValid() = 0;
|
virtual bool IsValid() = 0;
|
||||||
|
|
||||||
virtual bool GetBanner(u32* _pBannerImage) = 0;
|
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight) = 0;
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames() = 0;
|
virtual std::vector<std::string> GetNames() = 0;
|
||||||
virtual std::string GetCompany() = 0;
|
virtual std::string GetCompany() = 0;
|
||||||
|
@ -50,17 +50,15 @@ bool CBannerLoaderGC::IsValid()
|
|||||||
return m_IsValid;
|
return m_IsValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBannerLoaderGC::GetBanner(u32* _pBannerImage)
|
std::vector<u32> CBannerLoaderGC::GetBanner(int* pWidth, int* pHeight)
|
||||||
{
|
{
|
||||||
if (!IsValid())
|
std::vector<u32> Buffer;
|
||||||
{
|
Buffer.resize(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const pBanner = (DVDBanner*)m_pBannerFile;
|
auto const pBanner = (DVDBanner*)m_pBannerFile;
|
||||||
decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
|
decode5A3image(&Buffer[0], pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
|
||||||
|
*pWidth = DVD_BANNER_WIDTH;
|
||||||
return true;
|
*pHeight = DVD_BANNER_HEIGHT;
|
||||||
|
return std::move(Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class CBannerLoaderGC
|
|||||||
|
|
||||||
virtual bool IsValid();
|
virtual bool IsValid();
|
||||||
|
|
||||||
virtual bool GetBanner(u32* _pBannerImage);
|
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight);
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames();
|
virtual std::vector<std::string> GetNames();
|
||||||
virtual std::string GetCompany();
|
virtual std::string GetCompany();
|
||||||
|
@ -98,38 +98,15 @@ bool CBannerLoaderWii::IsValid()
|
|||||||
return m_IsValid;
|
return m_IsValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 Average32(u32 a, u32 b) {
|
std::vector<u32> CBannerLoaderWii::GetBanner(int* pWidth, int* pHeight)
|
||||||
return ((a >> 1) & 0x7f7f7f7f) + ((b >> 1) & 0x7f7f7f7f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 GetPixel(u32 *buffer, unsigned int x, unsigned int y) {
|
|
||||||
// thanks to unsignedness, these also check for <0 automatically.
|
|
||||||
if (x > 191) return 0;
|
|
||||||
if (y > 63) return 0;
|
|
||||||
return buffer[y * 192 + x];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CBannerLoaderWii::GetBanner(u32* _pBannerImage)
|
|
||||||
{
|
{
|
||||||
if (IsValid())
|
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
||||||
{
|
std::vector<u32> Buffer;
|
||||||
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
Buffer.resize(192 * 64);
|
||||||
u32* Buffer = new u32[192 * 64];
|
decode5A3image(&Buffer[0], (u16*)pBanner->m_BannerTexture, 192, 64);
|
||||||
decode5A3image(Buffer, (u16*)pBanner->m_BannerTexture, 192, 64);
|
*pWidth = 192;
|
||||||
for (int y = 0; y < 32; y++)
|
*pHeight = 64;
|
||||||
{
|
return std::move(Buffer);
|
||||||
for (int x = 0; x < 96; x++)
|
|
||||||
{
|
|
||||||
// simplified plus-shaped "gaussian"
|
|
||||||
u32 surround = Average32(
|
|
||||||
Average32(GetPixel(Buffer, x*2 - 1, y*2), GetPixel(Buffer, x*2 + 1, y*2)),
|
|
||||||
Average32(GetPixel(Buffer, x*2, y*2 - 1), GetPixel(Buffer, x*2, y*2 + 1)));
|
|
||||||
_pBannerImage[y * 96 + x] = Average32(GetPixel(Buffer, x*2, y*2), surround);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] Buffer;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result)
|
bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result)
|
||||||
|
@ -20,7 +20,7 @@ class CBannerLoaderWii
|
|||||||
|
|
||||||
virtual bool IsValid();
|
virtual bool IsValid();
|
||||||
|
|
||||||
virtual bool GetBanner(u32* _pBannerImage);
|
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight);
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames();
|
virtual std::vector<std::string> GetNames();
|
||||||
virtual std::string GetCompany();
|
virtual std::string GetCompany();
|
||||||
|
@ -402,8 +402,8 @@ void CGameListCtrl::InsertItemInReportView(long _Index)
|
|||||||
// Insert the platform's image in the first (visible) column
|
// Insert the platform's image in the first (visible) column
|
||||||
SetItemColumnImage(_Index, COLUMN_PLATFORM, m_PlatformImageIndex[rISOFile.GetPlatform()]);
|
SetItemColumnImage(_Index, COLUMN_PLATFORM, m_PlatformImageIndex[rISOFile.GetPlatform()]);
|
||||||
|
|
||||||
if (rISOFile.GetImage().IsOk())
|
if (rISOFile.GetBitmap().IsOk())
|
||||||
ImageIndex = m_imageListSmall->Add(rISOFile.GetImage());
|
ImageIndex = m_imageListSmall->Add(rISOFile.GetBitmap());
|
||||||
|
|
||||||
// Set the game's banner in the second column
|
// Set the game's banner in the second column
|
||||||
SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex);
|
SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex);
|
||||||
|
@ -24,13 +24,11 @@
|
|||||||
#include "ChunkFile.h"
|
#include "ChunkFile.h"
|
||||||
#include "ConfigManager.h"
|
#include "ConfigManager.h"
|
||||||
|
|
||||||
static const u32 CACHE_REVISION = 0x114;
|
static const u32 CACHE_REVISION = 0x115;
|
||||||
|
|
||||||
#define DVD_BANNER_WIDTH 96
|
#define DVD_BANNER_WIDTH 96
|
||||||
#define DVD_BANNER_HEIGHT 32
|
#define DVD_BANNER_HEIGHT 32
|
||||||
|
|
||||||
static u32 g_ImageTemp[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT];
|
|
||||||
|
|
||||||
GameListItem::GameListItem(const std::string& _rFileName)
|
GameListItem::GameListItem(const std::string& _rFileName)
|
||||||
: m_FileName(_rFileName)
|
: m_FileName(_rFileName)
|
||||||
, m_emu_state(0)
|
, m_emu_state(0)
|
||||||
@ -38,6 +36,8 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
, m_Revision(0)
|
, m_Revision(0)
|
||||||
, m_Valid(false)
|
, m_Valid(false)
|
||||||
, m_BlobCompressed(false)
|
, m_BlobCompressed(false)
|
||||||
|
, m_ImageWidth(0)
|
||||||
|
, m_ImageHeight(0)
|
||||||
{
|
{
|
||||||
if (LoadFromCache())
|
if (LoadFromCache())
|
||||||
{
|
{
|
||||||
@ -83,17 +83,16 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
m_company = pBannerLoader->GetCompany();
|
m_company = pBannerLoader->GetCompany();
|
||||||
m_descriptions = pBannerLoader->GetDescriptions();
|
m_descriptions = pBannerLoader->GetDescriptions();
|
||||||
|
|
||||||
if (pBannerLoader->GetBanner(g_ImageTemp))
|
std::vector<u32> Buffer = pBannerLoader->GetBanner(&m_ImageWidth, &m_ImageHeight);
|
||||||
{
|
u32* pData = &Buffer[0];
|
||||||
// resize vector to image size
|
// resize vector to image size
|
||||||
m_pImage.resize(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT * 3);
|
m_pImage.resize(m_ImageWidth * m_ImageHeight * 3);
|
||||||
|
|
||||||
for (size_t i = 0; i < DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT; i++)
|
for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++)
|
||||||
{
|
{
|
||||||
m_pImage[i * 3 + 0] = (g_ImageTemp[i] & 0xFF0000) >> 16;
|
m_pImage[i * 3 + 0] = (pData[i] & 0xFF0000) >> 16;
|
||||||
m_pImage[i * 3 + 1] = (g_ImageTemp[i] & 0x00FF00) >> 8;
|
m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8;
|
||||||
m_pImage[i * 3 + 2] = (g_ImageTemp[i] & 0x0000FF) >> 0;
|
m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete pBannerLoader;
|
delete pBannerLoader;
|
||||||
@ -124,12 +123,21 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
|
|
||||||
if (!m_pImage.empty())
|
if (!m_pImage.empty())
|
||||||
{
|
{
|
||||||
m_Image.Create(DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT, &m_pImage[0], true);
|
wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
|
||||||
|
double Scale = WxUtils::GetCurrentBitmapLogicalScale();
|
||||||
|
// Note: This uses nearest neighbor, which subjectively looks a lot
|
||||||
|
// better for GC banners than smooths caling.
|
||||||
|
Image.Rescale(DVD_BANNER_WIDTH * Scale, DVD_BANNER_HEIGHT * Scale);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
m_Bitmap = wxBitmap(Image, -1, Scale);
|
||||||
|
#else
|
||||||
|
m_Bitmap = wxBitmap(Image, -1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// default banner
|
// default banner
|
||||||
m_Image = wxImage(StrToWxStr(File::GetThemeDir(SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name)) + "nobanner.png", wxBITMAP_TYPE_PNG);
|
m_Bitmap.LoadFile(StrToWxStr(File::GetThemeDir(SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name)) + "nobanner.png", wxBITMAP_TYPE_PNG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +172,8 @@ void GameListItem::DoState(PointerWrap &p)
|
|||||||
p.Do(m_Country);
|
p.Do(m_Country);
|
||||||
p.Do(m_BlobCompressed);
|
p.Do(m_BlobCompressed);
|
||||||
p.Do(m_pImage);
|
p.Do(m_pImage);
|
||||||
|
p.Do(m_ImageWidth);
|
||||||
|
p.Do(m_ImageHeight);
|
||||||
p.Do(m_Platform);
|
p.Do(m_Platform);
|
||||||
p.Do(m_IsDiscTwo);
|
p.Do(m_IsDiscTwo);
|
||||||
p.Do(m_Revision);
|
p.Do(m_Revision);
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
u64 GetVolumeSize() const {return m_VolumeSize;}
|
u64 GetVolumeSize() const {return m_VolumeSize;}
|
||||||
bool IsDiscTwo() const {return m_IsDiscTwo;}
|
bool IsDiscTwo() const {return m_IsDiscTwo;}
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
const wxImage& GetImage() const {return m_Image;}
|
const wxBitmap& GetBitmap() const {return m_Bitmap;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
@ -78,11 +78,12 @@ private:
|
|||||||
int m_Revision;
|
int m_Revision;
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
wxImage m_Image;
|
wxBitmap m_Bitmap;
|
||||||
#endif
|
#endif
|
||||||
bool m_Valid;
|
bool m_Valid;
|
||||||
bool m_BlobCompressed;
|
bool m_BlobCompressed;
|
||||||
std::vector<u8> m_pImage;
|
std::vector<u8> m_pImage;
|
||||||
|
int m_ImageWidth, m_ImageHeight;
|
||||||
bool m_IsDiscTwo;
|
bool m_IsDiscTwo;
|
||||||
|
|
||||||
bool LoadFromCache();
|
bool LoadFromCache();
|
||||||
|
@ -215,7 +215,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
|||||||
ChangeBannerDetails(SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG"));
|
ChangeBannerDetails(SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG"));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Banner->SetBitmap(OpenGameListItem->GetImage());
|
m_Banner->SetBitmap(OpenGameListItem->GetBitmap());
|
||||||
m_Banner->Bind(wxEVT_RIGHT_DOWN, &CISOProperties::RightClickOnBanner, this);
|
m_Banner->Bind(wxEVT_RIGHT_DOWN, &CISOProperties::RightClickOnBanner, this);
|
||||||
|
|
||||||
// Filesystem browser/dumper
|
// Filesystem browser/dumper
|
||||||
|
@ -138,6 +138,17 @@ void Host_SetWiiMoteConnectionState(int _State) {}
|
|||||||
std::vector<std::string> m_volume_names;
|
std::vector<std::string> m_volume_names;
|
||||||
std::vector<std::string> m_names;
|
std::vector<std::string> m_names;
|
||||||
|
|
||||||
|
static inline u32 Average32(u32 a, u32 b) {
|
||||||
|
return ((a >> 1) & 0x7f7f7f7f) + ((b >> 1) & 0x7f7f7f7f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 GetPixel(u32 *buffer, unsigned int x, unsigned int y) {
|
||||||
|
// thanks to unsignedness, these also check for <0 automatically.
|
||||||
|
if (x > 191) return 0;
|
||||||
|
if (y > 63) return 0;
|
||||||
|
return buffer[y * 192 + x];
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadBanner(std::string filename, u32 *Banner)
|
bool LoadBanner(std::string filename, u32 *Banner)
|
||||||
{
|
{
|
||||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename);
|
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename);
|
||||||
@ -161,8 +172,32 @@ bool LoadBanner(std::string filename, u32 *Banner)
|
|||||||
if (pBannerLoader->IsValid())
|
if (pBannerLoader->IsValid())
|
||||||
{
|
{
|
||||||
m_names = pBannerLoader->GetNames();
|
m_names = pBannerLoader->GetNames();
|
||||||
if (pBannerLoader->GetBanner(Banner))
|
int Width, Height;
|
||||||
return true;
|
std::vector<u32> BannerVec = pBannerLoader->GetBanner(&Width, &Height);
|
||||||
|
// This code (along with above inlines) is moved from
|
||||||
|
// elsewhere. Someone who knows anything about Android
|
||||||
|
// please get rid of it and use proper high-resolution
|
||||||
|
// images.
|
||||||
|
if (Height == 64)
|
||||||
|
{
|
||||||
|
u32* Buffer = &BannerVec[0];
|
||||||
|
for (int y = 0; y < 32; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < 96; x++)
|
||||||
|
{
|
||||||
|
// simplified plus-shaped "gaussian"
|
||||||
|
u32 surround = Average32(
|
||||||
|
Average32(GetPixel(Buffer, x*2 - 1, y*2), GetPixel(Buffer, x*2 + 1, y*2)),
|
||||||
|
Average32(GetPixel(Buffer, x*2, y*2 - 1), GetPixel(Buffer, x*2, y*2 + 1)));
|
||||||
|
Banner[y * 96 + x] = Average32(GetPixel(Buffer, x*2, y*2), surround);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(Banner, &BannerVec[0], 96 * 32 * 4);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
#include "WxUtils.h"
|
#include "WxUtils.h"
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace WxUtils {
|
namespace WxUtils {
|
||||||
|
|
||||||
// Launch a file according to its mime type
|
// Launch a file according to its mime type
|
||||||
@ -40,6 +44,18 @@ void Explore(const char *path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GetCurrentBitmapLogicalScale()
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// wx doesn't expose this itself, unfortunately.
|
||||||
|
if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)])
|
||||||
|
{
|
||||||
|
return [[NSScreen mainScreen] backingScaleFactor];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string WxStrToStr(const wxString& str)
|
std::string WxStrToStr(const wxString& str)
|
||||||
|
@ -17,6 +17,8 @@ void Launch(const char *filename);
|
|||||||
// Launch an file explorer window on a certain path
|
// Launch an file explorer window on a certain path
|
||||||
void Explore(const char *path);
|
void Explore(const char *path);
|
||||||
|
|
||||||
|
double GetCurrentBitmapLogicalScale();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string WxStrToStr(const wxString& str);
|
std::string WxStrToStr(const wxString& str);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user