Merge pull request #2286 from JosJuice/wii-opening-bnr
Read opening.bnr to get names from Wii discs
This commit is contained in:
commit
6414cdabb2
|
@ -304,7 +304,7 @@ void SConfig::SaveGameListSettings(IniFile& ini)
|
||||||
|
|
||||||
gamelist->Set("ColumnPlatform", m_showSystemColumn);
|
gamelist->Set("ColumnPlatform", m_showSystemColumn);
|
||||||
gamelist->Set("ColumnBanner", m_showBannerColumn);
|
gamelist->Set("ColumnBanner", m_showBannerColumn);
|
||||||
gamelist->Set("ColumnNotes", m_showNotesColumn);
|
gamelist->Set("ColumnNotes", m_showMakerColumn);
|
||||||
gamelist->Set("ColumnID", m_showIDColumn);
|
gamelist->Set("ColumnID", m_showIDColumn);
|
||||||
gamelist->Set("ColumnRegion", m_showRegionColumn);
|
gamelist->Set("ColumnRegion", m_showRegionColumn);
|
||||||
gamelist->Set("ColumnSize", m_showSizeColumn);
|
gamelist->Set("ColumnSize", m_showSizeColumn);
|
||||||
|
@ -557,7 +557,7 @@ void SConfig::LoadGameListSettings(IniFile& ini)
|
||||||
// Gamelist columns toggles
|
// Gamelist columns toggles
|
||||||
gamelist->Get("ColumnPlatform", &m_showSystemColumn, true);
|
gamelist->Get("ColumnPlatform", &m_showSystemColumn, true);
|
||||||
gamelist->Get("ColumnBanner", &m_showBannerColumn, true);
|
gamelist->Get("ColumnBanner", &m_showBannerColumn, true);
|
||||||
gamelist->Get("ColumnNotes", &m_showNotesColumn, true);
|
gamelist->Get("ColumnNotes", &m_showMakerColumn, true);
|
||||||
gamelist->Get("ColumnID", &m_showIDColumn, false);
|
gamelist->Get("ColumnID", &m_showIDColumn, false);
|
||||||
gamelist->Get("ColumnRegion", &m_showRegionColumn, true);
|
gamelist->Get("ColumnRegion", &m_showRegionColumn, true);
|
||||||
gamelist->Get("ColumnSize", &m_showSizeColumn, true);
|
gamelist->Get("ColumnSize", &m_showSizeColumn, true);
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct SConfig : NonCopyable
|
||||||
// Game list column toggles
|
// Game list column toggles
|
||||||
bool m_showSystemColumn;
|
bool m_showSystemColumn;
|
||||||
bool m_showBannerColumn;
|
bool m_showBannerColumn;
|
||||||
bool m_showNotesColumn;
|
bool m_showMakerColumn;
|
||||||
bool m_showIDColumn;
|
bool m_showIDColumn;
|
||||||
bool m_showRegionColumn;
|
bool m_showRegionColumn;
|
||||||
bool m_showSizeColumn;
|
bool m_showSizeColumn;
|
||||||
|
|
|
@ -373,6 +373,20 @@ void SCoreStartupParameter::CheckMemcardPath(std::string& memcardPath, std::stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IVolume::ELanguage SCoreStartupParameter::GetCurrentLanguage(bool wii) const
|
||||||
|
{
|
||||||
|
IVolume::ELanguage language;
|
||||||
|
if (wii)
|
||||||
|
language = (IVolume::ELanguage)SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG");
|
||||||
|
else
|
||||||
|
language = (IVolume::ELanguage)(SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage + 1);
|
||||||
|
|
||||||
|
// Get rid of invalid values (probably doesn't matter, but might as well do it)
|
||||||
|
if (language > IVolume::ELanguage::LANGUAGE_UNKNOWN || language < 0)
|
||||||
|
language = IVolume::ELanguage::LANGUAGE_UNKNOWN;
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
IniFile SCoreStartupParameter::LoadDefaultGameIni() const
|
IniFile SCoreStartupParameter::LoadDefaultGameIni() const
|
||||||
{
|
{
|
||||||
return LoadDefaultGameIni(GetUniqueID(), m_revision);
|
return LoadDefaultGameIni(GetUniqueID(), m_revision);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Common/IniFile.h"
|
#include "Common/IniFile.h"
|
||||||
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
enum Hotkey
|
enum Hotkey
|
||||||
{
|
{
|
||||||
|
@ -248,6 +249,7 @@ struct SCoreStartupParameter
|
||||||
bool AutoSetup(EBootBS2 _BootBS2);
|
bool AutoSetup(EBootBS2 _BootBS2);
|
||||||
const std::string &GetUniqueID() const { return m_strUniqueID; }
|
const std::string &GetUniqueID() const { return m_strUniqueID; }
|
||||||
void CheckMemcardPath(std::string& memcardPath, std::string gameRegion, bool isSlotA);
|
void CheckMemcardPath(std::string& memcardPath, std::string gameRegion, bool isSlotA);
|
||||||
|
DiscIO::IVolume::ELanguage GetCurrentLanguage(bool wii) const;
|
||||||
|
|
||||||
IniFile LoadDefaultGameIni() const;
|
IniFile LoadDefaultGameIni() const;
|
||||||
IniFile LoadLocalGameIni() const;
|
IniFile LoadLocalGameIni() const;
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
#include "DiscIO/BannerLoaderGC.h"
|
|
||||||
#include "DiscIO/BannerLoaderWii.h"
|
|
||||||
#include "DiscIO/Filesystem.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
|
|
||||||
class IBannerLoader;
|
|
||||||
class IVolume;
|
|
||||||
|
|
||||||
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume)
|
|
||||||
{
|
|
||||||
if (pVolume->IsWiiDisc() || pVolume->IsWadFile())
|
|
||||||
return new CBannerLoaderWii(pVolume);
|
|
||||||
if (_rFileSystem.IsValid())
|
|
||||||
return new CBannerLoaderGC(_rFileSystem, pVolume);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -1,47 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
|
|
||||||
class IFileSystem;
|
|
||||||
class IVolume;
|
|
||||||
|
|
||||||
class IBannerLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IBannerLoader()
|
|
||||||
: m_IsValid(false)
|
|
||||||
, m_pBannerFile(nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual ~IBannerLoader()
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight) = 0;
|
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames() = 0;
|
|
||||||
virtual std::string GetCompany() = 0;
|
|
||||||
virtual std::vector<std::string> GetDescriptions() = 0;
|
|
||||||
|
|
||||||
bool IsValid()
|
|
||||||
{
|
|
||||||
return m_IsValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool m_IsValid;
|
|
||||||
u8* m_pBannerFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume);
|
|
||||||
|
|
||||||
} // namespace DiscIO
|
|
|
@ -1,183 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Common/ColorUtil.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "Common/MsgHandler.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
|
||||||
#include "DiscIO/BannerLoaderGC.h"
|
|
||||||
#include "DiscIO/Filesystem.h"
|
|
||||||
#include "DiscIO/Volume.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume)
|
|
||||||
: m_country(volume->GetCountry())
|
|
||||||
{
|
|
||||||
// load the opening.bnr
|
|
||||||
size_t FileSize = (size_t) _rFileSystem.GetFileSize("opening.bnr");
|
|
||||||
if (FileSize == BNR1_SIZE || FileSize == BNR2_SIZE)
|
|
||||||
{
|
|
||||||
m_pBannerFile = new u8[FileSize];
|
|
||||||
if (m_pBannerFile)
|
|
||||||
{
|
|
||||||
_rFileSystem.ReadFile("opening.bnr", m_pBannerFile, FileSize);
|
|
||||||
m_BNRType = getBannerType();
|
|
||||||
if (m_BNRType == BANNER_UNKNOWN)
|
|
||||||
PanicAlertT("Invalid opening.bnr found in gcm:\n%s\n You may need to redump this game.",
|
|
||||||
_rFileSystem.GetVolume()->GetName().c_str());
|
|
||||||
else m_IsValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else WARN_LOG(DISCIO, "Invalid opening.bnr size: %0lx",
|
|
||||||
(unsigned long)FileSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CBannerLoaderGC::~CBannerLoaderGC()
|
|
||||||
{
|
|
||||||
if (m_pBannerFile)
|
|
||||||
{
|
|
||||||
delete [] m_pBannerFile;
|
|
||||||
m_pBannerFile = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u32> CBannerLoaderGC::GetBanner(int* pWidth, int* pHeight)
|
|
||||||
{
|
|
||||||
std::vector<u32> Buffer;
|
|
||||||
Buffer.resize(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT);
|
|
||||||
auto const pBanner = (DVDBanner*)m_pBannerFile;
|
|
||||||
ColorUtil::decode5A3image(&Buffer[0], pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
|
|
||||||
*pWidth = DVD_BANNER_WIDTH;
|
|
||||||
*pHeight = DVD_BANNER_HEIGHT;
|
|
||||||
return Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string> CBannerLoaderGC::GetNames()
|
|
||||||
{
|
|
||||||
std::vector<std::string> names;
|
|
||||||
|
|
||||||
if (!IsValid())
|
|
||||||
{
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 name_count = 0;
|
|
||||||
|
|
||||||
// find Banner type
|
|
||||||
switch (m_BNRType)
|
|
||||||
{
|
|
||||||
case CBannerLoaderGC::BANNER_BNR1:
|
|
||||||
name_count = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CBannerLoaderGC::BANNER_BNR2:
|
|
||||||
name_count = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const banner = reinterpret_cast<const DVDBanner*>(m_pBannerFile);
|
|
||||||
|
|
||||||
for (u32 i = 0; i != name_count; ++i)
|
|
||||||
{
|
|
||||||
auto& comment = banner->comment[i];
|
|
||||||
|
|
||||||
if (comment.longTitle[0])
|
|
||||||
{
|
|
||||||
auto& data = comment.longTitle;
|
|
||||||
names.push_back(GetDecodedString(data));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& data = comment.shortTitle;
|
|
||||||
names.push_back(GetDecodedString(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string CBannerLoaderGC::GetCompany()
|
|
||||||
{
|
|
||||||
std::string company;
|
|
||||||
|
|
||||||
if (IsValid())
|
|
||||||
{
|
|
||||||
auto const pBanner = (DVDBanner*)m_pBannerFile;
|
|
||||||
auto& data = pBanner->comment[0].shortMaker;
|
|
||||||
company = GetDecodedString(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string> CBannerLoaderGC::GetDescriptions()
|
|
||||||
{
|
|
||||||
std::vector<std::string> descriptions;
|
|
||||||
|
|
||||||
if (!IsValid())
|
|
||||||
{
|
|
||||||
return descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 desc_count = 0;
|
|
||||||
|
|
||||||
// find Banner type
|
|
||||||
switch (m_BNRType)
|
|
||||||
{
|
|
||||||
case CBannerLoaderGC::BANNER_BNR1:
|
|
||||||
desc_count = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// English, German, French, Spanish, Italian, Dutch
|
|
||||||
case CBannerLoaderGC::BANNER_BNR2:
|
|
||||||
desc_count = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto banner = reinterpret_cast<const DVDBanner*>(m_pBannerFile);
|
|
||||||
|
|
||||||
for (u32 i = 0; i != desc_count; ++i)
|
|
||||||
{
|
|
||||||
auto& data = banner->comment[i].comment;
|
|
||||||
descriptions.push_back(GetDecodedString(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
return descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
CBannerLoaderGC::BANNER_TYPE CBannerLoaderGC::getBannerType()
|
|
||||||
{
|
|
||||||
u32 bannerSignature = *(u32*)m_pBannerFile;
|
|
||||||
CBannerLoaderGC::BANNER_TYPE type = CBannerLoaderGC::BANNER_UNKNOWN;
|
|
||||||
switch (bannerSignature)
|
|
||||||
{
|
|
||||||
// "BNR1"
|
|
||||||
case 0x31524e42:
|
|
||||||
type = CBannerLoaderGC::BANNER_BNR1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// "BNR2"
|
|
||||||
case 0x32524e42:
|
|
||||||
type = CBannerLoaderGC::BANNER_BNR2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -1,86 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
#include "DiscIO/Volume.h"
|
|
||||||
#include "DiscIO/VolumeGC.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
|
|
||||||
class IFileSystem;
|
|
||||||
|
|
||||||
class CBannerLoaderGC
|
|
||||||
: public IBannerLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume);
|
|
||||||
virtual ~CBannerLoaderGC();
|
|
||||||
|
|
||||||
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight) override;
|
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames() override;
|
|
||||||
virtual std::string GetCompany() override;
|
|
||||||
virtual std::vector<std::string> GetDescriptions() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DVD_BANNER_WIDTH = 96,
|
|
||||||
DVD_BANNER_HEIGHT = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BANNER_TYPE
|
|
||||||
{
|
|
||||||
BANNER_UNKNOWN,
|
|
||||||
BANNER_BNR1,
|
|
||||||
BANNER_BNR2,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Banner Comment
|
|
||||||
struct DVDBannerComment
|
|
||||||
{
|
|
||||||
char shortTitle[32]; // Short game title shown in IPL menu
|
|
||||||
char shortMaker[32]; // Short developer, publisher names shown in IPL menu
|
|
||||||
char longTitle[64]; // Long game title shown in IPL game start screen
|
|
||||||
char longMaker[64]; // Long developer, publisher names shown in IPL game start screen
|
|
||||||
char comment[128]; // Game description shown in IPL game start screen in two lines.
|
|
||||||
};
|
|
||||||
|
|
||||||
// "opening.bnr" file format for EU console
|
|
||||||
struct DVDBanner
|
|
||||||
{
|
|
||||||
u32 id; // 'BNR2'
|
|
||||||
u32 padding[7];
|
|
||||||
u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image
|
|
||||||
DVDBannerComment comment[6]; // Comments in six languages (only 1 for BNR1 type)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u32 BNR1_SIZE = sizeof(DVDBanner) - sizeof(DVDBannerComment) * 5;
|
|
||||||
static const u32 BNR2_SIZE = sizeof(DVDBanner);
|
|
||||||
|
|
||||||
template <u32 N>
|
|
||||||
std::string GetDecodedString(const char (&data)[N])
|
|
||||||
{
|
|
||||||
auto const string_decoder = CVolumeGC::GetStringDecoder(m_country);
|
|
||||||
|
|
||||||
// strnlen to trim NULLs
|
|
||||||
return string_decoder(std::string(data, strnlen(data, sizeof(data))));
|
|
||||||
}
|
|
||||||
|
|
||||||
BANNER_TYPE m_BNRType;
|
|
||||||
BANNER_TYPE getBannerType();
|
|
||||||
|
|
||||||
DiscIO::IVolume::ECountry const m_country;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -1,117 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Common/ColorUtil.h"
|
|
||||||
#include "Common/CommonFuncs.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "Common/FileUtil.h"
|
|
||||||
#include "Common/StringUtil.h"
|
|
||||||
|
|
||||||
#include "DiscIO/BannerLoaderWii.h"
|
|
||||||
#include "DiscIO/Volume.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
|
|
||||||
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IVolume *pVolume)
|
|
||||||
{
|
|
||||||
u64 TitleID = 0;
|
|
||||||
pVolume->GetTitleID((u8*)&TitleID);
|
|
||||||
TitleID = Common::swap64(TitleID);
|
|
||||||
|
|
||||||
std::string Filename = StringFromFormat("%stitle/%08x/%08x/data/banner.bin",
|
|
||||||
File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(TitleID>>32), (u32)TitleID);
|
|
||||||
|
|
||||||
if (!File::Exists(Filename))
|
|
||||||
{
|
|
||||||
m_IsValid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the banner.bin
|
|
||||||
size_t FileSize = (size_t) File::GetSize(Filename);
|
|
||||||
|
|
||||||
if (FileSize > 0)
|
|
||||||
{
|
|
||||||
m_pBannerFile = new u8[FileSize];
|
|
||||||
File::IOFile pFile(Filename, "rb");
|
|
||||||
if (pFile)
|
|
||||||
{
|
|
||||||
pFile.ReadBytes(m_pBannerFile, FileSize);
|
|
||||||
m_IsValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CBannerLoaderWii::~CBannerLoaderWii()
|
|
||||||
{
|
|
||||||
if (m_pBannerFile)
|
|
||||||
{
|
|
||||||
delete [] m_pBannerFile;
|
|
||||||
m_pBannerFile = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u32> CBannerLoaderWii::GetBanner(int* pWidth, int* pHeight)
|
|
||||||
{
|
|
||||||
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
|
||||||
std::vector<u32> Buffer;
|
|
||||||
Buffer.resize(192 * 64);
|
|
||||||
ColorUtil::decode5A3image(&Buffer[0], (u16*)pBanner->m_BannerTexture, 192, 64);
|
|
||||||
*pWidth = 192;
|
|
||||||
*pHeight = 64;
|
|
||||||
return Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result)
|
|
||||||
{
|
|
||||||
if (IsValid())
|
|
||||||
{
|
|
||||||
auto const banner = reinterpret_cast<const SWiiBanner*>(m_pBannerFile);
|
|
||||||
auto const src_ptr = banner->m_Comment[index];
|
|
||||||
|
|
||||||
// Trim at first nullptr
|
|
||||||
auto const length = std::find(src_ptr, src_ptr + COMMENT_SIZE, 0x0) - src_ptr;
|
|
||||||
|
|
||||||
std::wstring src;
|
|
||||||
src.resize(length);
|
|
||||||
std::transform(src_ptr, src_ptr + src.size(), src.begin(), (u16(&)(u16))Common::swap16);
|
|
||||||
result = UTF16ToUTF8(src);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> CBannerLoaderWii::GetNames()
|
|
||||||
{
|
|
||||||
std::vector<std::string> ret(1);
|
|
||||||
|
|
||||||
if (!GetStringFromComments(NAME_IDX, ret[0]))
|
|
||||||
ret.clear();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CBannerLoaderWii::GetCompany()
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> CBannerLoaderWii::GetDescriptions()
|
|
||||||
{
|
|
||||||
std::vector<std::string> result(1);
|
|
||||||
if (!GetStringFromComments(DESC_IDX, result[0]))
|
|
||||||
result.clear();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -1,63 +0,0 @@
|
||||||
// Copyright 2013 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
|
|
||||||
namespace DiscIO
|
|
||||||
{
|
|
||||||
|
|
||||||
class IVolume;
|
|
||||||
|
|
||||||
class CBannerLoaderWii
|
|
||||||
: public IBannerLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CBannerLoaderWii(DiscIO::IVolume *pVolume);
|
|
||||||
|
|
||||||
virtual ~CBannerLoaderWii();
|
|
||||||
|
|
||||||
virtual std::vector<u32> GetBanner(int* pWidth, int* pHeight) override;
|
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNames() override;
|
|
||||||
virtual std::string GetCompany() override;
|
|
||||||
virtual std::vector<std::string> GetDescriptions() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TEXTURE_SIZE = 192 * 64 * 2,
|
|
||||||
ICON_SIZE = 48 * 48 * 2,
|
|
||||||
COMMENT_SIZE = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CommentIndex
|
|
||||||
{
|
|
||||||
NAME_IDX,
|
|
||||||
DESC_IDX
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SWiiBanner
|
|
||||||
{
|
|
||||||
u32 ID;
|
|
||||||
|
|
||||||
u32 m_Flag;
|
|
||||||
u16 m_Speed;
|
|
||||||
u8 m_Unknown[22];
|
|
||||||
|
|
||||||
// Not null terminated!
|
|
||||||
u16 m_Comment[2][COMMENT_SIZE];
|
|
||||||
u8 m_BannerTexture[TEXTURE_SIZE];
|
|
||||||
u8 m_IconTexture[8][ICON_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
bool GetStringFromComments(const CommentIndex index, std::string& s);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
|
@ -1,7 +1,4 @@
|
||||||
set(SRCS BannerLoader.cpp
|
set(SRCS Blob.cpp
|
||||||
BannerLoaderGC.cpp
|
|
||||||
BannerLoaderWii.cpp
|
|
||||||
Blob.cpp
|
|
||||||
CISOBlob.cpp
|
CISOBlob.cpp
|
||||||
WbfsBlob.cpp
|
WbfsBlob.cpp
|
||||||
CompressedBlob.cpp
|
CompressedBlob.cpp
|
||||||
|
|
|
@ -35,9 +35,6 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="BannerLoader.cpp" />
|
|
||||||
<ClCompile Include="BannerLoaderGC.cpp" />
|
|
||||||
<ClCompile Include="BannerLoaderWii.cpp" />
|
|
||||||
<ClCompile Include="Blob.cpp" />
|
<ClCompile Include="Blob.cpp" />
|
||||||
<ClCompile Include="CISOBlob.cpp" />
|
<ClCompile Include="CISOBlob.cpp" />
|
||||||
<ClCompile Include="CompressedBlob.cpp" />
|
<ClCompile Include="CompressedBlob.cpp" />
|
||||||
|
@ -58,9 +55,6 @@
|
||||||
<ClCompile Include="WiiWad.cpp" />
|
<ClCompile Include="WiiWad.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BannerLoader.h" />
|
|
||||||
<ClInclude Include="BannerLoaderGC.h" />
|
|
||||||
<ClInclude Include="BannerLoaderWii.h" />
|
|
||||||
<ClInclude Include="Blob.h" />
|
<ClInclude Include="Blob.h" />
|
||||||
<ClInclude Include="CISOBlob.h" />
|
<ClInclude Include="CISOBlob.h" />
|
||||||
<ClInclude Include="CompressedBlob.h" />
|
<ClInclude Include="CompressedBlob.h" />
|
||||||
|
|
|
@ -24,15 +24,6 @@
|
||||||
<ClCompile Include="DiscScrubber.cpp">
|
<ClCompile Include="DiscScrubber.cpp">
|
||||||
<Filter>DiscScrubber</Filter>
|
<Filter>DiscScrubber</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="BannerLoader.cpp">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="BannerLoaderGC.cpp">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="BannerLoaderWii.cpp">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Filesystem.cpp">
|
<ClCompile Include="Filesystem.cpp">
|
||||||
<Filter>FileSystem</Filter>
|
<Filter>FileSystem</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -89,15 +80,6 @@
|
||||||
<ClInclude Include="DiscScrubber.h">
|
<ClInclude Include="DiscScrubber.h">
|
||||||
<Filter>DiscScrubber</Filter>
|
<Filter>DiscScrubber</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="BannerLoaderWii.h">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="BannerLoader.h">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="BannerLoaderGC.h">
|
|
||||||
<Filter>FileHandler</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Filesystem.h">
|
<ClInclude Include="Filesystem.h">
|
||||||
<Filter>FileSystem</Filter>
|
<Filter>FileSystem</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -63,7 +63,7 @@ const std::string CFileSystemGCWii::GetFileName(u64 _Address)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 CFileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
|
u64 CFileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile)
|
||||||
{
|
{
|
||||||
if (!m_Initialized)
|
if (!m_Initialized)
|
||||||
InitFileSystem();
|
InitFileSystem();
|
||||||
|
@ -72,14 +72,16 @@ u64 CFileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size
|
||||||
if (pFileInfo == nullptr)
|
if (pFileInfo == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
if (_OffsetInFile >= pFileInfo->m_FileSize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUG_LOG(DISCIO, "Filename: %s. Offset: %" PRIx64 ". Size: %" PRIx64, _rFullPath.c_str(),
|
u64 read_length = std::min(_MaxBufferSize, pFileInfo->m_FileSize - _OffsetInFile);
|
||||||
pFileInfo->m_Offset, pFileInfo->m_FileSize);
|
|
||||||
|
|
||||||
m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer, m_Wii);
|
DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 " Size: %" PRIx64,
|
||||||
return pFileInfo->m_FileSize;
|
read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->m_Offset, pFileInfo->m_FileSize);
|
||||||
|
|
||||||
|
m_rVolume->Read(pFileInfo->m_Offset + _OffsetInFile, read_length, _pBuffer, m_Wii);
|
||||||
|
return read_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFileSystemGCWii::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
|
bool CFileSystemGCWii::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
virtual u64 GetFileSize(const std::string& _rFullPath) override;
|
virtual u64 GetFileSize(const std::string& _rFullPath) override;
|
||||||
virtual size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) override;
|
virtual size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) override;
|
||||||
virtual const std::string GetFileName(u64 _Address) override;
|
virtual const std::string GetFileName(u64 _Address) override;
|
||||||
virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize) override;
|
virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) override;
|
||||||
virtual bool ExportFile(const std::string& _rFullPath, const std::string&_rExportFilename) override;
|
virtual bool ExportFile(const std::string& _rFullPath, const std::string&_rExportFilename) override;
|
||||||
virtual bool ExportApploader(const std::string& _rExportFolder) const override;
|
virtual bool ExportApploader(const std::string& _rExportFolder) const override;
|
||||||
virtual bool ExportDOL(const std::string& _rExportFolder) const override;
|
virtual bool ExportDOL(const std::string& _rExportFolder) const override;
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
virtual bool IsValid() const = 0;
|
virtual bool IsValid() const = 0;
|
||||||
virtual size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) = 0;
|
virtual size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) = 0;
|
||||||
virtual u64 GetFileSize(const std::string& _rFullPath) = 0;
|
virtual u64 GetFileSize(const std::string& _rFullPath) = 0;
|
||||||
virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize) = 0;
|
virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile = 0) = 0;
|
||||||
virtual bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) = 0;
|
virtual bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) = 0;
|
||||||
virtual bool ExportApploader(const std::string& _rExportFolder) const = 0;
|
virtual bool ExportApploader(const std::string& _rExportFolder) const = 0;
|
||||||
virtual bool ExportDOL(const std::string& _rExportFolder) const = 0;
|
virtual bool ExportDOL(const std::string& _rExportFolder) const = 0;
|
||||||
|
|
|
@ -4,18 +4,57 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
class IVolume
|
class IVolume
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Increment CACHE_REVISION if the enums below are modified (ISOFile.cpp & GameFile.cpp)
|
||||||
|
enum ECountry
|
||||||
|
{
|
||||||
|
COUNTRY_EUROPE = 0,
|
||||||
|
COUNTRY_JAPAN,
|
||||||
|
COUNTRY_USA,
|
||||||
|
COUNTRY_AUSTRALIA,
|
||||||
|
COUNTRY_FRANCE,
|
||||||
|
COUNTRY_GERMANY,
|
||||||
|
COUNTRY_ITALY,
|
||||||
|
COUNTRY_KOREA,
|
||||||
|
COUNTRY_NETHERLANDS,
|
||||||
|
COUNTRY_RUSSIA,
|
||||||
|
COUNTRY_SPAIN,
|
||||||
|
COUNTRY_TAIWAN,
|
||||||
|
COUNTRY_WORLD,
|
||||||
|
COUNTRY_UNKNOWN,
|
||||||
|
NUMBER_OF_COUNTRIES
|
||||||
|
};
|
||||||
|
|
||||||
|
// Languages 0 - 9 match the official Wii language numbering.
|
||||||
|
// Languages 1 - 6 match the official GC PAL languages 0 - 5.
|
||||||
|
enum ELanguage
|
||||||
|
{
|
||||||
|
LANGUAGE_JAPANESE = 0,
|
||||||
|
LANGUAGE_ENGLISH = 1,
|
||||||
|
LANGUAGE_GERMAN = 2,
|
||||||
|
LANGUAGE_FRENCH = 3,
|
||||||
|
LANGUAGE_SPANISH = 4,
|
||||||
|
LANGUAGE_ITALIAN = 5,
|
||||||
|
LANGUAGE_DUTCH = 6,
|
||||||
|
LANGUAGE_SIMPLIFIED_CHINESE = 7,
|
||||||
|
LANGUAGE_TRADITIONAL_CHINESE = 8,
|
||||||
|
LANGUAGE_KOREAN = 9,
|
||||||
|
LANGUAGE_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
IVolume() {}
|
IVolume() {}
|
||||||
virtual ~IVolume() {}
|
virtual ~IVolume() {}
|
||||||
|
|
||||||
|
@ -36,10 +75,12 @@ public:
|
||||||
}
|
}
|
||||||
virtual std::string GetUniqueID() const = 0;
|
virtual std::string GetUniqueID() const = 0;
|
||||||
virtual std::string GetMakerID() const = 0;
|
virtual std::string GetMakerID() const = 0;
|
||||||
virtual int GetRevision() const { return 0; }
|
virtual int GetRevision() const = 0;
|
||||||
// TODO: eliminate?
|
virtual std::string GetName() const = 0;
|
||||||
virtual std::string GetName() const;
|
virtual std::map<ELanguage, std::string> GetNames() const = 0;
|
||||||
virtual std::vector<std::string> GetNames() const = 0;
|
virtual std::map<ELanguage, std::string> GetDescriptions() const { return std::map<ELanguage, std::string>(); }
|
||||||
|
virtual std::string GetCompany() const { return std::string(); }
|
||||||
|
virtual std::vector<u32> GetBanner(int* width, int* height) const;
|
||||||
virtual u32 GetFSTSize() const = 0;
|
virtual u32 GetFSTSize() const = 0;
|
||||||
virtual std::string GetApploaderDate() const = 0;
|
virtual std::string GetApploaderDate() const = 0;
|
||||||
|
|
||||||
|
@ -50,31 +91,35 @@ public:
|
||||||
virtual bool CheckIntegrity() const { return false; }
|
virtual bool CheckIntegrity() const { return false; }
|
||||||
virtual bool ChangePartition(u64 offset) { return false; }
|
virtual bool ChangePartition(u64 offset) { return false; }
|
||||||
|
|
||||||
// Increment CACHE_REVISION if the code below is modified (ISOFile.cpp & GameFile.cpp)
|
|
||||||
enum ECountry
|
|
||||||
{
|
|
||||||
COUNTRY_EUROPE = 0,
|
|
||||||
COUNTRY_JAPAN,
|
|
||||||
COUNTRY_USA,
|
|
||||||
COUNTRY_AUSTRALIA,
|
|
||||||
COUNTRY_FRANCE,
|
|
||||||
COUNTRY_GERMANY,
|
|
||||||
COUNTRY_ITALY,
|
|
||||||
COUNTRY_KOREA,
|
|
||||||
COUNTRY_NETHERLANDS,
|
|
||||||
COUNTRY_RUSSIA,
|
|
||||||
COUNTRY_SPAIN,
|
|
||||||
COUNTRY_TAIWAN,
|
|
||||||
COUNTRY_WORLD,
|
|
||||||
COUNTRY_UNKNOWN,
|
|
||||||
NUMBER_OF_COUNTRIES
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ECountry GetCountry() const = 0;
|
virtual ECountry GetCountry() const = 0;
|
||||||
virtual u64 GetSize() const = 0;
|
virtual u64 GetSize() const = 0;
|
||||||
|
|
||||||
// Size on disc (compressed size)
|
// Size on disc (compressed size)
|
||||||
virtual u64 GetRawSize() const = 0;
|
virtual u64 GetRawSize() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <u32 N>
|
||||||
|
std::string DecodeString(const char(&data)[N]) const
|
||||||
|
{
|
||||||
|
// strnlen to trim NULLs
|
||||||
|
std::string string(data, strnlen(data, sizeof(data)));
|
||||||
|
|
||||||
|
// There don't seem to be any GC discs with the country set to Taiwan...
|
||||||
|
// But maybe they would use Shift_JIS if they existed? Not sure
|
||||||
|
bool use_shift_jis = (COUNTRY_JAPAN == GetCountry() || COUNTRY_TAIWAN == GetCountry());
|
||||||
|
|
||||||
|
if (use_shift_jis)
|
||||||
|
return SHIFTJISToUTF8(string);
|
||||||
|
else
|
||||||
|
return CP1252ToUTF8(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<IVolume::ELanguage, std::string> ReadWiiNames(std::vector<u8>& data);
|
||||||
|
|
||||||
|
static const size_t NUMBER_OF_LANGUAGES = 10;
|
||||||
|
static const size_t NAME_STRING_LENGTH = 42;
|
||||||
|
static const size_t NAME_BYTES_LENGTH = NAME_STRING_LENGTH * sizeof(u16);
|
||||||
|
static const size_t NAMES_TOTAL_BYTES = NAME_BYTES_LENGTH * NUMBER_OF_LANGUAGES;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic Switch function for all volumes
|
// Generic Switch function for all volumes
|
||||||
|
|
|
@ -2,16 +2,83 @@
|
||||||
// Licensed under GPLv2
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common/ColorUtil.h"
|
||||||
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
// Increment CACHE_REVISION if the code below is modified (ISOFile.cpp & GameFile.cpp)
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const unsigned int WII_BANNER_WIDTH = 192;
|
||||||
|
static const unsigned int WII_BANNER_HEIGHT = 64;
|
||||||
|
static const unsigned int WII_BANNER_SIZE = WII_BANNER_WIDTH * WII_BANNER_HEIGHT * 2;
|
||||||
|
static const unsigned int WII_BANNER_OFFSET = 0xA0;
|
||||||
|
|
||||||
|
std::vector<u32> IVolume::GetBanner(int* width, int* height) const
|
||||||
|
{
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
|
||||||
|
u64 TitleID = 0;
|
||||||
|
GetTitleID((u8*)&TitleID);
|
||||||
|
TitleID = Common::swap64(TitleID);
|
||||||
|
|
||||||
|
std::string file_name = StringFromFormat("%stitle/%08x/%08x/data/banner.bin",
|
||||||
|
File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(TitleID >> 32), (u32)TitleID);
|
||||||
|
if (!File::Exists(file_name))
|
||||||
|
return std::vector<u32>();
|
||||||
|
|
||||||
|
if (File::GetSize(file_name) < WII_BANNER_OFFSET + WII_BANNER_SIZE)
|
||||||
|
return std::vector<u32>();
|
||||||
|
|
||||||
|
File::IOFile file(file_name, "rb");
|
||||||
|
if (!file.Seek(WII_BANNER_OFFSET, SEEK_SET))
|
||||||
|
return std::vector<u32>();
|
||||||
|
|
||||||
|
std::vector<u8> banner_file(WII_BANNER_SIZE);
|
||||||
|
if (!file.ReadBytes(banner_file.data(), banner_file.size()))
|
||||||
|
return std::vector<u32>();
|
||||||
|
|
||||||
|
std::vector<u32> image_buffer(WII_BANNER_WIDTH * WII_BANNER_HEIGHT);
|
||||||
|
ColorUtil::decode5A3image(image_buffer.data(), (u16*)banner_file.data(), WII_BANNER_WIDTH, WII_BANNER_HEIGHT);
|
||||||
|
|
||||||
|
*width = WII_BANNER_WIDTH;
|
||||||
|
*height = WII_BANNER_HEIGHT;
|
||||||
|
return image_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<IVolume::ELanguage, std::string> IVolume::ReadWiiNames(std::vector<u8>& data)
|
||||||
|
{
|
||||||
|
std::map<IVolume::ELanguage, std::string> names;
|
||||||
|
for (size_t i = 0; i < NUMBER_OF_LANGUAGES; ++i)
|
||||||
|
{
|
||||||
|
size_t name_start = NAME_BYTES_LENGTH * i;
|
||||||
|
size_t name_end = name_start + NAME_BYTES_LENGTH;
|
||||||
|
if (data.size() >= name_end)
|
||||||
|
{
|
||||||
|
u16* temp = (u16*)(data.data() + name_start);
|
||||||
|
std::wstring out_temp(NAME_STRING_LENGTH, '\0');
|
||||||
|
std::transform(temp, temp + out_temp.size(), out_temp.begin(), (u16(&)(u16))Common::swap16);
|
||||||
|
out_temp.erase(std::find(out_temp.begin(), out_temp.end(), 0x00), out_temp.end());
|
||||||
|
std::string name = UTF16ToUTF8(out_temp);
|
||||||
|
if (!name.empty())
|
||||||
|
names[(IVolume::ELanguage)i] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment CACHE_REVISION if the code below is modified (ISOFile.cpp & GameFile.cpp)
|
||||||
IVolume::ECountry CountrySwitch(u8 country_code)
|
IVolume::ECountry CountrySwitch(u8 country_code)
|
||||||
{
|
{
|
||||||
switch (country_code)
|
switch (country_code)
|
||||||
|
@ -98,13 +165,4 @@ u8 GetSysMenuRegion(u16 _TitleVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IVolume::GetName() const
|
|
||||||
{
|
|
||||||
auto names = GetNames();
|
|
||||||
if (names.empty())
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return names[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
|
@ -183,9 +182,22 @@ std::string CVolumeDirectory::GetMakerID() const
|
||||||
return "VOID";
|
return "VOID";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CVolumeDirectory::GetNames() const
|
std::string CVolumeDirectory::GetName() const
|
||||||
{
|
{
|
||||||
return std::vector<std::string>(1, (char*)(&m_diskHeader[0x20]));
|
char name[0x60];
|
||||||
|
if (Read(0x20, 0x60, (u8*)name, false))
|
||||||
|
return DecodeString(name);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<IVolume::ELanguage, std::string> CVolumeDirectory::GetNames() const
|
||||||
|
{
|
||||||
|
std::map<IVolume::ELanguage, std::string> names;
|
||||||
|
std::string name = GetName();
|
||||||
|
if (!name.empty())
|
||||||
|
names[IVolume::ELanguage::LANGUAGE_UNKNOWN] = name;
|
||||||
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVolumeDirectory::SetName(const std::string& name)
|
void CVolumeDirectory::SetName(const std::string& name)
|
||||||
|
|
|
@ -39,7 +39,9 @@ public:
|
||||||
|
|
||||||
std::string GetMakerID() const override;
|
std::string GetMakerID() const override;
|
||||||
|
|
||||||
std::vector<std::string> GetNames() const override;
|
int GetRevision() const override { return 0; }
|
||||||
|
std::string GetName() const override;
|
||||||
|
std::map<IVolume::ELanguage, std::string> GetNames() const override;
|
||||||
void SetName(const std::string&);
|
void SetName(const std::string&);
|
||||||
|
|
||||||
u32 GetFSTSize() const override;
|
u32 GetFSTSize() const override;
|
||||||
|
|
|
@ -3,14 +3,18 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common/ColorUtil.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
#include "DiscIO/Blob.h"
|
#include "DiscIO/Blob.h"
|
||||||
#include "DiscIO/FileMonitor.h"
|
#include "DiscIO/FileMonitor.h"
|
||||||
|
#include "DiscIO/Filesystem.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
#include "DiscIO/VolumeGC.h"
|
#include "DiscIO/VolumeGC.h"
|
||||||
|
|
||||||
|
@ -92,19 +96,133 @@ int CVolumeGC::GetRevision() const
|
||||||
return revision;
|
return revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CVolumeGC::GetNames() const
|
std::string CVolumeGC::GetName() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> names;
|
char name[0x60];
|
||||||
|
|
||||||
auto const string_decoder = GetStringDecoder(GetCountry());
|
|
||||||
|
|
||||||
char name[0x60 + 1] = {};
|
|
||||||
if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)name))
|
if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)name))
|
||||||
names.push_back(string_decoder(name));
|
return DecodeString(name);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<IVolume::ELanguage, std::string> CVolumeGC::GetNames() const
|
||||||
|
{
|
||||||
|
std::map<IVolume::ELanguage, std::string> names;
|
||||||
|
|
||||||
|
if (!LoadBannerFile())
|
||||||
|
return names;
|
||||||
|
|
||||||
|
u32 name_count = 0;
|
||||||
|
IVolume::ELanguage language;
|
||||||
|
bool is_japanese = GetCountry() == IVolume::ECountry::COUNTRY_JAPAN;
|
||||||
|
|
||||||
|
switch (m_banner_file_type)
|
||||||
|
{
|
||||||
|
case BANNER_BNR1:
|
||||||
|
name_count = 1;
|
||||||
|
language = is_japanese ? IVolume::ELanguage::LANGUAGE_JAPANESE : IVolume::ELanguage::LANGUAGE_ENGLISH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BANNER_BNR2:
|
||||||
|
name_count = 6;
|
||||||
|
language = IVolume::ELanguage::LANGUAGE_ENGLISH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BANNER_INVALID:
|
||||||
|
case BANNER_NOT_LOADED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const banner = reinterpret_cast<const GCBanner*>(m_banner_file.data());
|
||||||
|
|
||||||
|
for (u32 i = 0; i < name_count; ++i)
|
||||||
|
{
|
||||||
|
auto& comment = banner->comment[i];
|
||||||
|
std::string name = DecodeString(comment.longTitle);
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
|
name = DecodeString(comment.shortTitle);
|
||||||
|
|
||||||
|
if (!name.empty())
|
||||||
|
names[(IVolume::ELanguage)(language + i)] = name;
|
||||||
|
}
|
||||||
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<IVolume::ELanguage, std::string> CVolumeGC::GetDescriptions() const
|
||||||
|
{
|
||||||
|
std::map<IVolume::ELanguage, std::string> descriptions;
|
||||||
|
|
||||||
|
if (!LoadBannerFile())
|
||||||
|
return descriptions;
|
||||||
|
|
||||||
|
u32 desc_count = 0;
|
||||||
|
IVolume::ELanguage language;
|
||||||
|
bool is_japanese = GetCountry() == IVolume::ECountry::COUNTRY_JAPAN;
|
||||||
|
|
||||||
|
switch (m_banner_file_type)
|
||||||
|
{
|
||||||
|
case BANNER_BNR1:
|
||||||
|
desc_count = 1;
|
||||||
|
language = is_japanese ? IVolume::ELanguage::LANGUAGE_JAPANESE : IVolume::ELanguage::LANGUAGE_ENGLISH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BANNER_BNR2:
|
||||||
|
language = IVolume::ELanguage::LANGUAGE_ENGLISH;
|
||||||
|
desc_count = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BANNER_INVALID:
|
||||||
|
case BANNER_NOT_LOADED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto banner = reinterpret_cast<const GCBanner*>(m_banner_file.data());
|
||||||
|
|
||||||
|
for (u32 i = 0; i < desc_count; ++i)
|
||||||
|
{
|
||||||
|
auto& data = banner->comment[i].comment;
|
||||||
|
std::string description = DecodeString(data);
|
||||||
|
|
||||||
|
if (!description.empty())
|
||||||
|
descriptions[(IVolume::ELanguage)(language + i)] = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CVolumeGC::GetCompany() const
|
||||||
|
{
|
||||||
|
if (!LoadBannerFile())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
auto const pBanner = (GCBanner*)m_banner_file.data();
|
||||||
|
std::string company = DecodeString(pBanner->comment[0].longMaker);
|
||||||
|
|
||||||
|
if (company.empty())
|
||||||
|
company = DecodeString(pBanner->comment[0].shortMaker);
|
||||||
|
|
||||||
|
return company;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u32> CVolumeGC::GetBanner(int* width, int* height) const
|
||||||
|
{
|
||||||
|
if (!LoadBannerFile())
|
||||||
|
{
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
return std::vector<u32>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u32> image_buffer(GC_BANNER_WIDTH * GC_BANNER_HEIGHT);
|
||||||
|
auto const pBanner = (GCBanner*)m_banner_file.data();
|
||||||
|
ColorUtil::decode5A3image(image_buffer.data(), pBanner->image, GC_BANNER_WIDTH, GC_BANNER_HEIGHT);
|
||||||
|
*width = GC_BANNER_WIDTH;
|
||||||
|
*height = GC_BANNER_HEIGHT;
|
||||||
|
return image_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
u32 CVolumeGC::GetFSTSize() const
|
u32 CVolumeGC::GetFSTSize() const
|
||||||
{
|
{
|
||||||
if (m_pReader == nullptr)
|
if (m_pReader == nullptr)
|
||||||
|
@ -154,10 +272,46 @@ bool CVolumeGC::IsDiscTwo() const
|
||||||
return (disc_two_check == 1);
|
return (disc_two_check == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CVolumeGC::StringDecoder CVolumeGC::GetStringDecoder(ECountry country)
|
bool CVolumeGC::LoadBannerFile() const
|
||||||
{
|
{
|
||||||
return (COUNTRY_JAPAN == country || COUNTRY_TAIWAN == country) ?
|
// The methods GetNames, GetDescriptions, GetCompany and GetBanner
|
||||||
SHIFTJISToUTF8 : CP1252ToUTF8;
|
// all need to access the opening.bnr file. These four methods are
|
||||||
|
// typically called after each other, so we store the file in RAM
|
||||||
|
// to avoid reading it from the disc several times. However,
|
||||||
|
// if none of these methods are called, the file is never loaded.
|
||||||
|
|
||||||
|
if (m_banner_file_type != BANNER_NOT_LOADED)
|
||||||
|
return m_banner_file_type != BANNER_INVALID;
|
||||||
|
|
||||||
|
std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
|
||||||
|
size_t file_size = (size_t)file_system->GetFileSize("opening.bnr");
|
||||||
|
if (file_size == BNR1_SIZE || file_size == BNR2_SIZE)
|
||||||
|
{
|
||||||
|
m_banner_file.resize(file_size);
|
||||||
|
file_system->ReadFile("opening.bnr", m_banner_file.data(), m_banner_file.size());
|
||||||
|
|
||||||
|
u32 bannerSignature = *(u32*)m_banner_file.data();
|
||||||
|
switch (bannerSignature)
|
||||||
|
{
|
||||||
|
case 0x31524e42: // "BNR1"
|
||||||
|
m_banner_file_type = BANNER_BNR1;
|
||||||
|
break;
|
||||||
|
case 0x32524e42: // "BNR2"
|
||||||
|
m_banner_file_type = BANNER_BNR2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_banner_file_type = BANNER_INVALID;
|
||||||
|
WARN_LOG(DISCIO, "Invalid opening.bnr type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_banner_file_type = BANNER_INVALID;
|
||||||
|
WARN_LOG(DISCIO, "Invalid opening.bnr size: %0lx", (unsigned long)file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_banner_file_type != BANNER_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -27,7 +28,11 @@ public:
|
||||||
std::string GetUniqueID() const override;
|
std::string GetUniqueID() const override;
|
||||||
std::string GetMakerID() const override;
|
std::string GetMakerID() const override;
|
||||||
int GetRevision() const override;
|
int GetRevision() const override;
|
||||||
std::vector<std::string> GetNames() const override;
|
virtual std::string GetName() const override;
|
||||||
|
std::map<ELanguage, std::string> GetNames() const override;
|
||||||
|
std::map<ELanguage, std::string> GetDescriptions() const override;
|
||||||
|
std::string GetCompany() const override;
|
||||||
|
std::vector<u32> GetBanner(int* width, int* height) const override;
|
||||||
u32 GetFSTSize() const override;
|
u32 GetFSTSize() const override;
|
||||||
std::string GetApploaderDate() const override;
|
std::string GetApploaderDate() const override;
|
||||||
|
|
||||||
|
@ -37,11 +42,44 @@ public:
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
u64 GetRawSize() const override;
|
u64 GetRawSize() const override;
|
||||||
|
|
||||||
typedef std::string(*StringDecoder)(const std::string&);
|
|
||||||
|
|
||||||
static StringDecoder GetStringDecoder(ECountry country);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool LoadBannerFile() const;
|
||||||
|
|
||||||
|
static const int GC_BANNER_WIDTH = 96;
|
||||||
|
static const int GC_BANNER_HEIGHT = 32;
|
||||||
|
|
||||||
|
// Banner Comment
|
||||||
|
struct GCBannerComment
|
||||||
|
{
|
||||||
|
char shortTitle[32]; // Short game title shown in IPL menu
|
||||||
|
char shortMaker[32]; // Short developer, publisher names shown in IPL menu
|
||||||
|
char longTitle[64]; // Long game title shown in IPL game start screen
|
||||||
|
char longMaker[64]; // Long developer, publisher names shown in IPL game start screen
|
||||||
|
char comment[128]; // Game description shown in IPL game start screen in two lines.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GCBanner
|
||||||
|
{
|
||||||
|
u32 id; // "BNR1" for NTSC, "BNR2" for PAL
|
||||||
|
u32 padding[7];
|
||||||
|
u16 image[GC_BANNER_WIDTH * GC_BANNER_HEIGHT]; // RGB5A3 96x32 image
|
||||||
|
GCBannerComment comment[6]; // Comments in six languages (only one for BNR1 type)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t BNR1_SIZE = sizeof(GCBanner) - sizeof(GCBannerComment) * 5;
|
||||||
|
static const size_t BNR2_SIZE = sizeof(GCBanner);
|
||||||
|
|
||||||
|
enum BannerFileType
|
||||||
|
{
|
||||||
|
BANNER_NOT_LOADED,
|
||||||
|
BANNER_INVALID,
|
||||||
|
BANNER_BNR1,
|
||||||
|
BANNER_BNR2
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable BannerFileType m_banner_file_type = BANNER_NOT_LOADED;
|
||||||
|
mutable std::vector<u8> m_banner_file;
|
||||||
|
|
||||||
std::unique_ptr<IBlobReader> m_pReader;
|
std::unique_ptr<IBlobReader> m_pReader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Licensed under GPLv2
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -117,42 +117,12 @@ bool CVolumeWAD::IsWadFile() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CVolumeWAD::GetNames() const
|
std::map<IVolume::ELanguage, std::string> CVolumeWAD::GetNames() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> names;
|
std::vector<u8> name_data(NAMES_TOTAL_BYTES);
|
||||||
|
if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, name_data.data()))
|
||||||
u32 footer_size;
|
return std::map<IVolume::ELanguage, std::string>();
|
||||||
if (!Read(0x1C, 4, (u8*)&footer_size))
|
return ReadWiiNames(name_data);
|
||||||
{
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer_size = Common::swap32(footer_size);
|
|
||||||
|
|
||||||
//Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean
|
|
||||||
for (int i = 0; i != 10; ++i)
|
|
||||||
{
|
|
||||||
static const u32 string_length = 42;
|
|
||||||
static const u32 bytes_length = string_length * sizeof(u16);
|
|
||||||
|
|
||||||
u16 temp[string_length];
|
|
||||||
|
|
||||||
if (footer_size < 0xF1 || !Read(0x9C + (i * bytes_length) + m_opening_bnr_offset, bytes_length, (u8*)&temp))
|
|
||||||
{
|
|
||||||
names.push_back("");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::wstring out_temp;
|
|
||||||
out_temp.resize(string_length);
|
|
||||||
std::transform(temp, temp + out_temp.size(), out_temp.begin(), (u16(&)(u16))Common::swap16);
|
|
||||||
out_temp.erase(std::find(out_temp.begin(), out_temp.end(), 0x00), out_temp.end());
|
|
||||||
|
|
||||||
names.push_back(UTF16ToUTF8(out_temp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 CVolumeWAD::GetSize() const
|
u64 CVolumeWAD::GetSize() const
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -30,9 +31,10 @@ public:
|
||||||
std::string GetUniqueID() const override;
|
std::string GetUniqueID() const override;
|
||||||
std::string GetMakerID() const override;
|
std::string GetMakerID() const override;
|
||||||
int GetRevision() const override;
|
int GetRevision() const override;
|
||||||
std::vector<std::string> GetNames() const override;
|
std::string GetName() const override { return ""; }
|
||||||
|
std::map<IVolume::ELanguage, std::string> GetNames() const override;
|
||||||
u32 GetFSTSize() const override { return 0; }
|
u32 GetFSTSize() const override { return 0; }
|
||||||
std::string GetApploaderDate() const override { return "0"; }
|
std::string GetApploaderDate() const override { return ""; }
|
||||||
|
|
||||||
bool IsWadFile() const override;
|
bool IsWadFile() const override;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <polarssl/aes.h>
|
#include <polarssl/aes.h>
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "DiscIO/Blob.h"
|
#include "DiscIO/Blob.h"
|
||||||
#include "DiscIO/FileMonitor.h"
|
#include "DiscIO/FileMonitor.h"
|
||||||
|
#include "DiscIO/Filesystem.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
#include "DiscIO/VolumeCreator.h"
|
#include "DiscIO/VolumeCreator.h"
|
||||||
#include "DiscIO/VolumeGC.h"
|
#include "DiscIO/VolumeGC.h"
|
||||||
|
@ -191,17 +193,21 @@ int CVolumeWiiCrypted::GetRevision() const
|
||||||
return revision;
|
return revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CVolumeWiiCrypted::GetNames() const
|
std::string CVolumeWiiCrypted::GetName() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> names;
|
char name_buffer[0x60];
|
||||||
|
if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)&name_buffer, false))
|
||||||
|
return DecodeString(name_buffer);
|
||||||
|
|
||||||
auto const string_decoder = CVolumeGC::GetStringDecoder(GetCountry());
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
char name[0xFF] = {};
|
std::map<IVolume::ELanguage, std::string> CVolumeWiiCrypted::GetNames() const
|
||||||
if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)&name, true))
|
{
|
||||||
names.push_back(string_decoder(name));
|
std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
|
||||||
|
std::vector<u8> opening_bnr(NAMES_TOTAL_BYTES);
|
||||||
return names;
|
opening_bnr.resize(file_system->ReadFile("opening.bnr", opening_bnr.data(), opening_bnr.size(), 0x5C));
|
||||||
|
return ReadWiiNames(opening_bnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CVolumeWiiCrypted::GetFSTSize() const
|
u32 CVolumeWiiCrypted::GetFSTSize() const
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -30,7 +31,8 @@ public:
|
||||||
std::string GetUniqueID() const override;
|
std::string GetUniqueID() const override;
|
||||||
std::string GetMakerID() const override;
|
std::string GetMakerID() const override;
|
||||||
int GetRevision() const override;
|
int GetRevision() const override;
|
||||||
std::vector<std::string> GetNames() const override;
|
std::string GetName() const override;
|
||||||
|
std::map<IVolume::ELanguage, std::string> GetNames() const override;
|
||||||
u32 GetFSTSize() const override;
|
u32 GetFSTSize() const override;
|
||||||
std::string GetApploaderDate() const override;
|
std::string GetApploaderDate() const override;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
#include "DiscIO/CompressedBlob.h"
|
#include "DiscIO/CompressedBlob.h"
|
||||||
#include "DiscIO/Filesystem.h"
|
#include "DiscIO/Filesystem.h"
|
||||||
|
|
||||||
|
@ -26,25 +25,50 @@
|
||||||
#include "DolphinQt/Utils/Resources.h"
|
#include "DolphinQt/Utils/Resources.h"
|
||||||
#include "DolphinQt/Utils/Utils.h"
|
#include "DolphinQt/Utils/Utils.h"
|
||||||
|
|
||||||
static const u32 CACHE_REVISION = 0x006;
|
static const u32 CACHE_REVISION = 0x007;
|
||||||
static const u32 DATASTREAM_REVISION = 15; // Introduced in Qt 5.2
|
static const u32 DATASTREAM_REVISION = 15; // Introduced in Qt 5.2
|
||||||
|
|
||||||
static QStringList VectorToStringList(std::vector<std::string> vec, bool trim = false)
|
static QMap<IVolume::ELanguage, QString> ConvertLocalizedStrings(std::map<IVolume::ELanguage, std::string> strings)
|
||||||
{
|
{
|
||||||
QStringList result;
|
QMap<IVolume::ELanguage, QString> result;
|
||||||
if (trim)
|
|
||||||
{
|
for (auto entry : strings)
|
||||||
for (const std::string& member : vec)
|
result.insert(entry.first, QString::fromStdString(entry.second).trimmed());
|
||||||
result.append(QString::fromStdString(member).trimmed());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const std::string& member : vec)
|
|
||||||
result.append(QString::fromStdString(member));
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class to, class from>
|
||||||
|
static QMap<to, QString> CastLocalizedStrings(QMap<from, QString> strings)
|
||||||
|
{
|
||||||
|
QMap<to, QString> result;
|
||||||
|
|
||||||
|
auto end = strings.cend();
|
||||||
|
for (auto it = strings.cbegin(); it != end; ++it)
|
||||||
|
result.insert((to)it.key(), it.value());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString GetLanguageString(IVolume::ELanguage language, QMap<IVolume::ELanguage, QString> strings)
|
||||||
|
{
|
||||||
|
if (strings.contains(language))
|
||||||
|
return strings.value(language);
|
||||||
|
|
||||||
|
// English tends to be a good fallback when the requested language isn't available
|
||||||
|
if (language != IVolume::ELanguage::LANGUAGE_ENGLISH)
|
||||||
|
{
|
||||||
|
if (strings.contains(IVolume::ELanguage::LANGUAGE_ENGLISH))
|
||||||
|
return strings.value(IVolume::ELanguage::LANGUAGE_ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If English isn't available either, just pick something
|
||||||
|
if (!strings.empty())
|
||||||
|
return strings.cbegin().value();
|
||||||
|
|
||||||
|
return SL("");
|
||||||
|
}
|
||||||
|
|
||||||
GameFile::GameFile(const QString& fileName)
|
GameFile::GameFile(const QString& fileName)
|
||||||
: m_file_name(fileName)
|
: m_file_name(fileName)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +81,7 @@ GameFile::GameFile(const QString& fileName)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DiscIO::IVolume* volume = DiscIO::CreateVolumeFromFilename(fileName.toStdString());
|
std::unique_ptr<DiscIO::IVolume> volume(DiscIO::CreateVolumeFromFilename(fileName.toStdString()));
|
||||||
|
|
||||||
if (volume != nullptr)
|
if (volume != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +90,9 @@ GameFile::GameFile(const QString& fileName)
|
||||||
else
|
else
|
||||||
m_platform = WII_WAD;
|
m_platform = WII_WAD;
|
||||||
|
|
||||||
m_volume_names = VectorToStringList(volume->GetNames());
|
m_names = ConvertLocalizedStrings(volume->GetNames());
|
||||||
|
m_descriptions = ConvertLocalizedStrings(volume->GetDescriptions());
|
||||||
|
m_company = QString::fromStdString(volume->GetCompany());
|
||||||
|
|
||||||
m_country = volume->GetCountry();
|
m_country = volume->GetCountry();
|
||||||
m_file_size = volume->GetRawSize();
|
m_file_size = volume->GetRawSize();
|
||||||
|
@ -80,24 +106,8 @@ GameFile::GameFile(const QString& fileName)
|
||||||
QFileInfo info(m_file_name);
|
QFileInfo info(m_file_name);
|
||||||
m_folder_name = info.absoluteDir().dirName();
|
m_folder_name = info.absoluteDir().dirName();
|
||||||
|
|
||||||
// check if we can get some info from the banner file too
|
|
||||||
DiscIO::IFileSystem* fileSystem = DiscIO::CreateFileSystem(volume);
|
|
||||||
|
|
||||||
if (fileSystem != nullptr || m_platform == WII_WAD)
|
|
||||||
{
|
|
||||||
std::unique_ptr<DiscIO::IBannerLoader> bannerLoader(DiscIO::CreateBannerLoader(*fileSystem, volume));
|
|
||||||
|
|
||||||
if (bannerLoader != nullptr)
|
|
||||||
{
|
|
||||||
if (bannerLoader->IsValid())
|
|
||||||
{
|
|
||||||
if (m_platform != WII_WAD)
|
|
||||||
m_names = VectorToStringList(bannerLoader->GetNames());
|
|
||||||
m_company = QString::fromStdString(bannerLoader->GetCompany());
|
|
||||||
m_descriptions = VectorToStringList(bannerLoader->GetDescriptions(), true);
|
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
std::vector<u32> buffer = bannerLoader->GetBanner(&width, &height);
|
std::vector<u32> buffer = volume->GetBanner(&width, &height);
|
||||||
QImage banner(width, height, QImage::Format_RGB888);
|
QImage banner(width, height, QImage::Format_RGB888);
|
||||||
for (int i = 0; i < width * height; i++)
|
for (int i = 0; i < width * height; i++)
|
||||||
{
|
{
|
||||||
|
@ -112,11 +122,6 @@ GameFile::GameFile(const QString& fileName)
|
||||||
hasBanner = true;
|
hasBanner = true;
|
||||||
m_banner = QPixmap::fromImage(banner);
|
m_banner = QPixmap::fromImage(banner);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
delete fileSystem;
|
|
||||||
}
|
|
||||||
delete volume;
|
|
||||||
|
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
if (hasBanner)
|
if (hasBanner)
|
||||||
|
@ -158,11 +163,13 @@ bool GameFile::LoadFromCache()
|
||||||
if (cache_rev != CACHE_REVISION)
|
if (cache_rev != CACHE_REVISION)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int country;
|
u32 country;
|
||||||
|
QMap<u8, QString> names;
|
||||||
|
QMap<u8, QString> descriptions;
|
||||||
stream >> m_folder_name
|
stream >> m_folder_name
|
||||||
>> m_volume_names
|
>> names
|
||||||
|
>> descriptions
|
||||||
>> m_company
|
>> m_company
|
||||||
>> m_descriptions
|
|
||||||
>> m_unique_id
|
>> m_unique_id
|
||||||
>> m_file_size
|
>> m_file_size
|
||||||
>> m_volume_size
|
>> m_volume_size
|
||||||
|
@ -173,6 +180,8 @@ bool GameFile::LoadFromCache()
|
||||||
>> m_is_disc_two
|
>> m_is_disc_two
|
||||||
>> m_revision;
|
>> m_revision;
|
||||||
m_country = (DiscIO::IVolume::ECountry)country;
|
m_country = (DiscIO::IVolume::ECountry)country;
|
||||||
|
m_names = CastLocalizedStrings<IVolume::ELanguage>(names);
|
||||||
|
m_descriptions = CastLocalizedStrings<IVolume::ELanguage>(descriptions);
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -198,13 +207,13 @@ void GameFile::SaveToCache()
|
||||||
stream << CACHE_REVISION;
|
stream << CACHE_REVISION;
|
||||||
|
|
||||||
stream << m_folder_name
|
stream << m_folder_name
|
||||||
<< m_volume_names
|
<< CastLocalizedStrings<u8>(m_names)
|
||||||
|
<< CastLocalizedStrings<u8>(m_descriptions)
|
||||||
<< m_company
|
<< m_company
|
||||||
<< m_descriptions
|
|
||||||
<< m_unique_id
|
<< m_unique_id
|
||||||
<< m_file_size
|
<< m_file_size
|
||||||
<< m_volume_size
|
<< m_volume_size
|
||||||
<< (int)m_country
|
<< (u32)m_country
|
||||||
<< m_banner
|
<< m_banner
|
||||||
<< m_compressed
|
<< m_compressed
|
||||||
<< m_platform
|
<< m_platform
|
||||||
|
@ -233,56 +242,27 @@ QString GameFile::CreateCacheFilename()
|
||||||
|
|
||||||
QString GameFile::GetCompany() const
|
QString GameFile::GetCompany() const
|
||||||
{
|
{
|
||||||
if (m_company.isEmpty())
|
|
||||||
return QObject::tr("N/A");
|
|
||||||
else
|
|
||||||
return m_company;
|
return m_company;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all of the following functions that accept an "index" parameter,
|
QString GameFile::GetDescription(IVolume::ELanguage language) const
|
||||||
// (-1 = Japanese, 0 = English, etc)?
|
|
||||||
|
|
||||||
QString GameFile::GetDescription(int index) const
|
|
||||||
{
|
{
|
||||||
if (index < m_descriptions.size())
|
return GetLanguageString(language, m_descriptions);
|
||||||
return m_descriptions[index];
|
|
||||||
|
|
||||||
if (!m_descriptions.empty())
|
|
||||||
return m_descriptions[0];
|
|
||||||
|
|
||||||
return SL("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GameFile::GetVolumeName(int index) const
|
QString GameFile::GetDescription() const
|
||||||
{
|
{
|
||||||
if (index < m_volume_names.size() && !m_volume_names[index].isEmpty())
|
return GetDescription(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC));
|
||||||
return m_volume_names[index];
|
|
||||||
|
|
||||||
if (!m_volume_names.isEmpty())
|
|
||||||
return m_volume_names[0];
|
|
||||||
|
|
||||||
return SL("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GameFile::GetBannerName(int index) const
|
QString GameFile::GetName(IVolume::ELanguage language) const
|
||||||
{
|
{
|
||||||
if (index < m_names.size() && !m_names[index].isEmpty())
|
return GetLanguageString(language, m_names);
|
||||||
return m_names[index];
|
|
||||||
|
|
||||||
if (!m_names.isEmpty())
|
|
||||||
return m_names[0];
|
|
||||||
|
|
||||||
return SL("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GameFile::GetName(int index) const
|
QString GameFile::GetName() const
|
||||||
{
|
{
|
||||||
// Prefer name from banner, fallback to name from volume, fallback to filename
|
QString name = GetName(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC));
|
||||||
QString name = GetBannerName(index);
|
|
||||||
|
|
||||||
if (name.isEmpty())
|
|
||||||
name = GetVolumeName(index);
|
|
||||||
|
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
{
|
{
|
||||||
// No usable name, return filename (better than nothing)
|
// No usable name, return filename (better than nothing)
|
||||||
|
@ -290,7 +270,6 @@ QString GameFile::GetName(int index) const
|
||||||
SplitPath(m_file_name.toStdString(), nullptr, &nametemp, nullptr);
|
SplitPath(m_file_name.toStdString(), nullptr, &nametemp, nullptr);
|
||||||
name = QString::fromStdString(nametemp);
|
name = QString::fromStdString(nametemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@ public:
|
||||||
bool IsValid() const { return m_valid; }
|
bool IsValid() const { return m_valid; }
|
||||||
QString GetFileName() { return m_file_name; }
|
QString GetFileName() { return m_file_name; }
|
||||||
QString GetFolderName() { return m_folder_name; }
|
QString GetFolderName() { return m_folder_name; }
|
||||||
QString GetBannerName(int index) const;
|
QString GetName(DiscIO::IVolume::ELanguage language) const;
|
||||||
QString GetVolumeName(int index) const;
|
QString GetName() const;
|
||||||
QString GetName(int index) const;
|
QString GetDescription(DiscIO::IVolume::ELanguage language) const;
|
||||||
|
QString GetDescription() const;
|
||||||
QString GetCompany() const;
|
QString GetCompany() const;
|
||||||
QString GetDescription(int index = 0) const;
|
|
||||||
int GetRevision() const { return m_revision; }
|
int GetRevision() const { return m_revision; }
|
||||||
const QString GetUniqueID() const { return m_unique_id; }
|
const QString GetUniqueID() const { return m_unique_id; }
|
||||||
const QString GetWiiFSPath() const;
|
const QString GetWiiFSPath() const;
|
||||||
|
@ -52,12 +52,9 @@ private:
|
||||||
QString m_file_name;
|
QString m_file_name;
|
||||||
QString m_folder_name;
|
QString m_folder_name;
|
||||||
|
|
||||||
// TODO: eliminate this and overwrite with names from banner when available?
|
QMap<DiscIO::IVolume::ELanguage, QString> m_names;
|
||||||
QStringList m_volume_names;
|
QMap<DiscIO::IVolume::ELanguage, QString> m_descriptions;
|
||||||
|
|
||||||
QString m_company;
|
QString m_company;
|
||||||
QStringList m_names;
|
|
||||||
QStringList m_descriptions;
|
|
||||||
|
|
||||||
QString m_unique_id;
|
QString m_unique_id;
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ void DGameGrid::AddGame(GameFile* gameItem)
|
||||||
QListWidgetItem* i = new QListWidgetItem;
|
QListWidgetItem* i = new QListWidgetItem;
|
||||||
i->setIcon(QIcon(gameItem->GetBitmap()
|
i->setIcon(QIcon(gameItem->GetBitmap()
|
||||||
.scaled(GRID_BANNER_WIDTH, GRID_BANNER_HEIGHT, Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
.scaled(GRID_BANNER_WIDTH, GRID_BANNER_HEIGHT, Qt::KeepAspectRatio, Qt::SmoothTransformation)));
|
||||||
i->setText(gameItem->GetName(0));
|
i->setText(gameItem->GetName());
|
||||||
if (gameItem->IsCompressed())
|
if (gameItem->IsCompressed())
|
||||||
i->setTextColor(QColor("#00F"));
|
i->setTextColor(QColor("#00F"));
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ void DGameTree::AddGame(GameFile* item)
|
||||||
QTreeWidgetItem* i = new QTreeWidgetItem;
|
QTreeWidgetItem* i = new QTreeWidgetItem;
|
||||||
i->setIcon(COL_TYPE, QIcon(Resources::GetPlatformPixmap(item->GetPlatform())));
|
i->setIcon(COL_TYPE, QIcon(Resources::GetPlatformPixmap(item->GetPlatform())));
|
||||||
i->setIcon(COL_BANNER, QIcon(item->GetBitmap()));
|
i->setIcon(COL_BANNER, QIcon(item->GetBitmap()));
|
||||||
i->setText(COL_TITLE, item->GetName(0));
|
i->setText(COL_TITLE, item->GetName());
|
||||||
i->setText(COL_DESCRIPTION, item->GetDescription());
|
i->setText(COL_DESCRIPTION, item->GetDescription());
|
||||||
i->setIcon(COL_REGION, QIcon(Resources::GetRegionPixmap(item->GetCountry())));
|
i->setIcon(COL_REGION, QIcon(Resources::GetRegionPixmap(item->GetCountry())));
|
||||||
i->setText(COL_SIZE, NiceSizeFormat(item->GetFileSize()));
|
i->setText(COL_SIZE, NiceSizeFormat(item->GetFileSize()));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
||||||
|
#include "DiscIO/Volume.h"
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
#include "DolphinWX/Config/WiiConfigPane.h"
|
#include "DolphinWX/Config/WiiConfigPane.h"
|
||||||
|
|
||||||
|
@ -125,7 +126,7 @@ void WiiConfigPane::OnConnectKeyboardCheckBoxChanged(wxCommandEvent& event)
|
||||||
|
|
||||||
void WiiConfigPane::OnSystemLanguageChoiceChanged(wxCommandEvent& event)
|
void WiiConfigPane::OnSystemLanguageChoiceChanged(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
int wii_system_lang = m_system_language_choice->GetSelection();
|
IVolume::ELanguage wii_system_lang = (IVolume::ELanguage)m_system_language_choice->GetSelection();
|
||||||
SConfig::GetInstance().m_SYSCONF->SetData("IPL.LNG", wii_system_lang);
|
SConfig::GetInstance().m_SYSCONF->SetData("IPL.LNG", wii_system_lang);
|
||||||
u8 country_code = GetSADRCountryCode(wii_system_lang);
|
u8 country_code = GetSADRCountryCode(wii_system_lang);
|
||||||
|
|
||||||
|
@ -138,41 +139,33 @@ void WiiConfigPane::OnAspectRatioChoiceChanged(wxCommandEvent& event)
|
||||||
SConfig::GetInstance().m_SYSCONF->SetData("IPL.AR", m_aspect_ratio_choice->GetSelection());
|
SConfig::GetInstance().m_SYSCONF->SetData("IPL.AR", m_aspect_ratio_choice->GetSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change from IPL.LNG value to IPL.SADR country code
|
// Change from IPL.LNG value to IPL.SADR country code.
|
||||||
u8 WiiConfigPane::GetSADRCountryCode(int language)
|
// http://wiibrew.org/wiki/Country_Codes
|
||||||
|
u8 WiiConfigPane::GetSADRCountryCode(IVolume::ELanguage language)
|
||||||
{
|
{
|
||||||
//http://wiibrew.org/wiki/Country_Codes
|
switch (language)
|
||||||
u8 country_code = language;
|
|
||||||
switch (country_code)
|
|
||||||
{
|
{
|
||||||
case 0: //Japanese
|
case IVolume::LANGUAGE_JAPANESE:
|
||||||
country_code = 1; //Japan
|
return 1; // Japan
|
||||||
break;
|
case IVolume::LANGUAGE_ENGLISH:
|
||||||
case 1: //English
|
return 49; // USA
|
||||||
country_code = 49; //USA
|
case IVolume::LANGUAGE_GERMAN:
|
||||||
break;
|
return 78; // Germany
|
||||||
case 2: //German
|
case IVolume::LANGUAGE_FRENCH:
|
||||||
country_code = 78; //Germany
|
return 77; // France
|
||||||
break;
|
case IVolume::LANGUAGE_SPANISH:
|
||||||
case 3: //French
|
return 105; // Spain
|
||||||
country_code = 77; //France
|
case IVolume::LANGUAGE_ITALIAN:
|
||||||
break;
|
return 83; // Italy
|
||||||
case 4: //Spanish
|
case IVolume::LANGUAGE_DUTCH:
|
||||||
country_code = 105; //Spain
|
return 94; // Netherlands
|
||||||
break;
|
case IVolume::LANGUAGE_SIMPLIFIED_CHINESE:
|
||||||
case 5: //Italian
|
case IVolume::LANGUAGE_TRADITIONAL_CHINESE:
|
||||||
country_code = 83; //Italy
|
return 157; // China
|
||||||
break;
|
case IVolume::LANGUAGE_KOREAN:
|
||||||
case 6: //Dutch
|
return 136; // Korea
|
||||||
country_code = 94; //Netherlands
|
|
||||||
break;
|
|
||||||
case 7: //Simplified Chinese
|
|
||||||
case 8: //Traditional Chinese
|
|
||||||
country_code = 157; //China
|
|
||||||
break;
|
|
||||||
case 9: //Korean
|
|
||||||
country_code = 136; //Korea
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return country_code;
|
|
||||||
|
PanicAlert("Invalid language");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <wx/arrstr.h>
|
#include <wx/arrstr.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
class wxCheckBox;
|
class wxCheckBox;
|
||||||
class wxChoice;
|
class wxChoice;
|
||||||
|
@ -29,7 +30,7 @@ private:
|
||||||
void OnSystemLanguageChoiceChanged(wxCommandEvent&);
|
void OnSystemLanguageChoiceChanged(wxCommandEvent&);
|
||||||
void OnAspectRatioChoiceChanged(wxCommandEvent&);
|
void OnAspectRatioChoiceChanged(wxCommandEvent&);
|
||||||
|
|
||||||
static u8 GetSADRCountryCode(int language);
|
static u8 GetSADRCountryCode(IVolume::ELanguage language);
|
||||||
|
|
||||||
wxArrayString m_system_language_strings;
|
wxArrayString m_system_language_strings;
|
||||||
wxArrayString m_aspect_ratio_strings;
|
wxArrayString m_aspect_ratio_strings;
|
||||||
|
|
|
@ -364,8 +364,8 @@ wxMenuBar* CFrame::CreateMenu()
|
||||||
columnsMenu->Check(IDM_SHOW_SYSTEM, SConfig::GetInstance().m_showSystemColumn);
|
columnsMenu->Check(IDM_SHOW_SYSTEM, SConfig::GetInstance().m_showSystemColumn);
|
||||||
columnsMenu->AppendCheckItem(IDM_SHOW_BANNER, _("Banner"));
|
columnsMenu->AppendCheckItem(IDM_SHOW_BANNER, _("Banner"));
|
||||||
columnsMenu->Check(IDM_SHOW_BANNER, SConfig::GetInstance().m_showBannerColumn);
|
columnsMenu->Check(IDM_SHOW_BANNER, SConfig::GetInstance().m_showBannerColumn);
|
||||||
columnsMenu->AppendCheckItem(IDM_SHOW_NOTES, _("Notes"));
|
columnsMenu->AppendCheckItem(IDM_SHOW_MAKER, _("Maker"));
|
||||||
columnsMenu->Check(IDM_SHOW_NOTES, SConfig::GetInstance().m_showNotesColumn);
|
columnsMenu->Check(IDM_SHOW_MAKER, SConfig::GetInstance().m_showMakerColumn);
|
||||||
columnsMenu->AppendCheckItem(IDM_SHOW_ID, _("Game ID"));
|
columnsMenu->AppendCheckItem(IDM_SHOW_ID, _("Game ID"));
|
||||||
columnsMenu->Check(IDM_SHOW_ID, SConfig::GetInstance().m_showIDColumn);
|
columnsMenu->Check(IDM_SHOW_ID, SConfig::GetInstance().m_showIDColumn);
|
||||||
columnsMenu->AppendCheckItem(IDM_SHOW_REGION, _("Region"));
|
columnsMenu->AppendCheckItem(IDM_SHOW_REGION, _("Region"));
|
||||||
|
@ -2035,8 +2035,8 @@ void CFrame::OnChangeColumnsVisible(wxCommandEvent& event)
|
||||||
case IDM_SHOW_BANNER:
|
case IDM_SHOW_BANNER:
|
||||||
SConfig::GetInstance().m_showBannerColumn = !SConfig::GetInstance().m_showBannerColumn;
|
SConfig::GetInstance().m_showBannerColumn = !SConfig::GetInstance().m_showBannerColumn;
|
||||||
break;
|
break;
|
||||||
case IDM_SHOW_NOTES:
|
case IDM_SHOW_MAKER:
|
||||||
SConfig::GetInstance().m_showNotesColumn = !SConfig::GetInstance().m_showNotesColumn;
|
SConfig::GetInstance().m_showMakerColumn = !SConfig::GetInstance().m_showMakerColumn;
|
||||||
break;
|
break;
|
||||||
case IDM_SHOW_ID:
|
case IDM_SHOW_ID:
|
||||||
SConfig::GetInstance().m_showIDColumn = !SConfig::GetInstance().m_showIDColumn;
|
SConfig::GetInstance().m_showIDColumn = !SConfig::GetInstance().m_showIDColumn;
|
||||||
|
|
|
@ -99,34 +99,13 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is
|
||||||
sortData = -sortData;
|
sortData = -sortData;
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOne = 0;
|
IVolume::ELanguage languageOne = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(iso1->GetPlatform() != GameListItem::GAMECUBE_DISC);
|
||||||
int indexOther = 0;
|
IVolume::ELanguage languageOther = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(iso2->GetPlatform() != GameListItem::GAMECUBE_DISC);
|
||||||
|
|
||||||
|
|
||||||
// index only matters for WADS and PAL GC games, but invalid indicies for the others
|
|
||||||
// will return the (only) language in the list
|
|
||||||
if (iso1->GetPlatform() == GameListItem::WII_WAD)
|
|
||||||
{
|
|
||||||
indexOne = SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG");
|
|
||||||
}
|
|
||||||
else // GC
|
|
||||||
{
|
|
||||||
indexOne = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iso2->GetPlatform() == GameListItem::WII_WAD)
|
|
||||||
{
|
|
||||||
indexOther = SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG");
|
|
||||||
}
|
|
||||||
else // GC
|
|
||||||
{
|
|
||||||
indexOther = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (sortData)
|
switch (sortData)
|
||||||
{
|
{
|
||||||
case CGameListCtrl::COLUMN_TITLE:
|
case CGameListCtrl::COLUMN_TITLE:
|
||||||
if (!strcasecmp(iso1->GetName(indexOne).c_str(),iso2->GetName(indexOther).c_str()))
|
if (!strcasecmp(iso1->GetName(languageOne).c_str(), iso2->GetName(languageOther).c_str()))
|
||||||
{
|
{
|
||||||
if (iso1->GetUniqueID() != iso2->GetUniqueID())
|
if (iso1->GetUniqueID() != iso2->GetUniqueID())
|
||||||
return t * (iso1->GetUniqueID() > iso2->GetUniqueID() ? 1 : -1);
|
return t * (iso1->GetUniqueID() > iso2->GetUniqueID() ? 1 : -1);
|
||||||
|
@ -135,18 +114,10 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is
|
||||||
if (iso1->IsDiscTwo() != iso2->IsDiscTwo())
|
if (iso1->IsDiscTwo() != iso2->IsDiscTwo())
|
||||||
return t * (iso1->IsDiscTwo() ? 1 : -1);
|
return t * (iso1->IsDiscTwo() ? 1 : -1);
|
||||||
}
|
}
|
||||||
return strcasecmp(iso1->GetName(indexOne).c_str(),
|
return strcasecmp(iso1->GetName(languageOne).c_str(),
|
||||||
iso2->GetName(indexOther).c_str()) * t;
|
iso2->GetName(languageOther).c_str()) * t;
|
||||||
case CGameListCtrl::COLUMN_NOTES:
|
case CGameListCtrl::COLUMN_MAKER:
|
||||||
{
|
return strcasecmp(iso1->GetCompany().c_str(), iso2->GetCompany().c_str()) * t;
|
||||||
std::string cmp1 =
|
|
||||||
(iso1->GetPlatform() == GameListItem::GAMECUBE_DISC) ?
|
|
||||||
iso1->GetCompany() : iso1->GetDescription(indexOne);
|
|
||||||
std::string cmp2 =
|
|
||||||
(iso2->GetPlatform() == GameListItem::GAMECUBE_DISC) ?
|
|
||||||
iso2->GetCompany() : iso2->GetDescription(indexOther);
|
|
||||||
return strcasecmp(cmp1.c_str(), cmp2.c_str()) * t;
|
|
||||||
}
|
|
||||||
case CGameListCtrl::COLUMN_ID:
|
case CGameListCtrl::COLUMN_ID:
|
||||||
return strcasecmp(iso1->GetUniqueID().c_str(), iso2->GetUniqueID().c_str()) * t;
|
return strcasecmp(iso1->GetUniqueID().c_str(), iso2->GetUniqueID().c_str()) * t;
|
||||||
case CGameListCtrl::COLUMN_COUNTRY:
|
case CGameListCtrl::COLUMN_COUNTRY:
|
||||||
|
@ -311,10 +282,7 @@ void CGameListCtrl::Update()
|
||||||
InsertColumn(COLUMN_BANNER, _("Banner"));
|
InsertColumn(COLUMN_BANNER, _("Banner"));
|
||||||
InsertColumn(COLUMN_TITLE, _("Title"));
|
InsertColumn(COLUMN_TITLE, _("Title"));
|
||||||
|
|
||||||
// Instead of showing the notes + the company, which is unknown with
|
InsertColumn(COLUMN_MAKER, _("Maker"));
|
||||||
// Wii titles We show in the same column : company for GC games and
|
|
||||||
// description for Wii/wad games
|
|
||||||
InsertColumn(COLUMN_NOTES, _("Notes"));
|
|
||||||
InsertColumn(COLUMN_ID, _("ID"));
|
InsertColumn(COLUMN_ID, _("ID"));
|
||||||
InsertColumn(COLUMN_COUNTRY, "");
|
InsertColumn(COLUMN_COUNTRY, "");
|
||||||
InsertColumn(COLUMN_SIZE, _("Size"));
|
InsertColumn(COLUMN_SIZE, _("Size"));
|
||||||
|
@ -331,7 +299,7 @@ void CGameListCtrl::Update()
|
||||||
SetColumnWidth(COLUMN_PLATFORM, SConfig::GetInstance().m_showSystemColumn ? 35 + platform_padding : 0);
|
SetColumnWidth(COLUMN_PLATFORM, SConfig::GetInstance().m_showSystemColumn ? 35 + platform_padding : 0);
|
||||||
SetColumnWidth(COLUMN_BANNER, SConfig::GetInstance().m_showBannerColumn ? 96 + platform_padding : 0);
|
SetColumnWidth(COLUMN_BANNER, SConfig::GetInstance().m_showBannerColumn ? 96 + platform_padding : 0);
|
||||||
SetColumnWidth(COLUMN_TITLE, 175 + platform_padding);
|
SetColumnWidth(COLUMN_TITLE, 175 + platform_padding);
|
||||||
SetColumnWidth(COLUMN_NOTES, SConfig::GetInstance().m_showNotesColumn ? 150 + platform_padding : 0);
|
SetColumnWidth(COLUMN_MAKER, SConfig::GetInstance().m_showMakerColumn ? 150 + platform_padding : 0);
|
||||||
SetColumnWidth(COLUMN_ID, SConfig::GetInstance().m_showIDColumn ? 75 + platform_padding : 0);
|
SetColumnWidth(COLUMN_ID, SConfig::GetInstance().m_showIDColumn ? 75 + platform_padding : 0);
|
||||||
SetColumnWidth(COLUMN_COUNTRY, SConfig::GetInstance().m_showRegionColumn ? 32 + platform_padding : 0);
|
SetColumnWidth(COLUMN_COUNTRY, SConfig::GetInstance().m_showRegionColumn ? 32 + platform_padding : 0);
|
||||||
SetColumnWidth(COLUMN_EMULATION_STATE, SConfig::GetInstance().m_showStateColumn ? 50 + platform_padding : 0);
|
SetColumnWidth(COLUMN_EMULATION_STATE, SConfig::GetInstance().m_showStateColumn ? 50 + platform_padding : 0);
|
||||||
|
@ -433,15 +401,7 @@ void CGameListCtrl::InsertItemInReportView(long _Index)
|
||||||
// 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);
|
||||||
|
|
||||||
int SelectedLanguage = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage;
|
std::string name = rISOFile.GetName();
|
||||||
|
|
||||||
// Is this sane?
|
|
||||||
if (rISOFile.GetPlatform() == GameListItem::WII_WAD)
|
|
||||||
{
|
|
||||||
SelectedLanguage = SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name = rISOFile.GetName(SelectedLanguage);
|
|
||||||
|
|
||||||
std::ifstream titlestxt;
|
std::ifstream titlestxt;
|
||||||
OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "titles.txt", std::ios::in);
|
OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "titles.txt", std::ios::in);
|
||||||
|
@ -470,12 +430,7 @@ void CGameListCtrl::InsertItemInReportView(long _Index)
|
||||||
name = title;
|
name = title;
|
||||||
|
|
||||||
SetItem(_Index, COLUMN_TITLE, StrToWxStr(name), -1);
|
SetItem(_Index, COLUMN_TITLE, StrToWxStr(name), -1);
|
||||||
|
SetItem(_Index, COLUMN_MAKER, StrToWxStr(rISOFile.GetCompany()), -1);
|
||||||
// We show the company string on GameCube only
|
|
||||||
// On Wii we show the description instead as the company string is empty
|
|
||||||
std::string const notes = (rISOFile.GetPlatform() == GameListItem::GAMECUBE_DISC) ?
|
|
||||||
rISOFile.GetCompany() : rISOFile.GetDescription(SelectedLanguage);
|
|
||||||
SetItem(_Index, COLUMN_NOTES, StrToWxStr(notes), -1);
|
|
||||||
|
|
||||||
// Emulation state
|
// Emulation state
|
||||||
SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[rISOFile.GetEmuState()]);
|
SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[rISOFile.GetEmuState()]);
|
||||||
|
@ -699,7 +654,7 @@ void CGameListCtrl::ScanForISOs()
|
||||||
|
|
||||||
void CGameListCtrl::OnColBeginDrag(wxListEvent& event)
|
void CGameListCtrl::OnColBeginDrag(wxListEvent& event)
|
||||||
{
|
{
|
||||||
if (event.GetColumn() != COLUMN_TITLE && event.GetColumn() != COLUMN_NOTES)
|
if (event.GetColumn() != COLUMN_TITLE && event.GetColumn() != COLUMN_MAKER)
|
||||||
event.Veto();
|
event.Veto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,13 +1303,13 @@ void CGameListCtrl::AutomaticColumnWidth()
|
||||||
+ GetColumnWidth(COLUMN_SIZE)
|
+ GetColumnWidth(COLUMN_SIZE)
|
||||||
+ GetColumnWidth(COLUMN_EMULATION_STATE));
|
+ GetColumnWidth(COLUMN_EMULATION_STATE));
|
||||||
|
|
||||||
// We hide the Notes column if the window is too small
|
// We hide the Maker column if the window is too small
|
||||||
if (resizable > 400)
|
if (resizable > 400)
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().m_showNotesColumn)
|
if (SConfig::GetInstance().m_showMakerColumn)
|
||||||
{
|
{
|
||||||
SetColumnWidth(COLUMN_TITLE, resizable / 2);
|
SetColumnWidth(COLUMN_TITLE, resizable / 2);
|
||||||
SetColumnWidth(COLUMN_NOTES, resizable / 2);
|
SetColumnWidth(COLUMN_MAKER, resizable / 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1364,7 +1319,7 @@ void CGameListCtrl::AutomaticColumnWidth()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetColumnWidth(COLUMN_TITLE, resizable);
|
SetColumnWidth(COLUMN_TITLE, resizable);
|
||||||
SetColumnWidth(COLUMN_NOTES, 0);
|
SetColumnWidth(COLUMN_MAKER, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
COLUMN_PLATFORM,
|
COLUMN_PLATFORM,
|
||||||
COLUMN_BANNER,
|
COLUMN_BANNER,
|
||||||
COLUMN_TITLE,
|
COLUMN_TITLE,
|
||||||
COLUMN_NOTES,
|
COLUMN_MAKER,
|
||||||
COLUMN_ID,
|
COLUMN_ID,
|
||||||
COLUMN_COUNTRY,
|
COLUMN_COUNTRY,
|
||||||
COLUMN_SIZE,
|
COLUMN_SIZE,
|
||||||
|
|
|
@ -176,7 +176,7 @@ enum
|
||||||
// List Column Title Toggles
|
// List Column Title Toggles
|
||||||
IDM_SHOW_SYSTEM,
|
IDM_SHOW_SYSTEM,
|
||||||
IDM_SHOW_BANNER,
|
IDM_SHOW_BANNER,
|
||||||
IDM_SHOW_NOTES,
|
IDM_SHOW_MAKER,
|
||||||
IDM_SHOW_ID,
|
IDM_SHOW_ID,
|
||||||
IDM_SHOW_REGION,
|
IDM_SHOW_REGION,
|
||||||
IDM_SHOW_SIZE,
|
IDM_SHOW_SIZE,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
|
@ -28,7 +29,6 @@
|
||||||
#include "Core/CoreParameter.h"
|
#include "Core/CoreParameter.h"
|
||||||
#include "Core/Boot/Boot.h"
|
#include "Core/Boot/Boot.h"
|
||||||
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
#include "DiscIO/CompressedBlob.h"
|
#include "DiscIO/CompressedBlob.h"
|
||||||
#include "DiscIO/Filesystem.h"
|
#include "DiscIO/Filesystem.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
@ -37,11 +37,33 @@
|
||||||
#include "DolphinWX/ISOFile.h"
|
#include "DolphinWX/ISOFile.h"
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
|
|
||||||
static const u32 CACHE_REVISION = 0x122;
|
static const u32 CACHE_REVISION = 0x123;
|
||||||
|
|
||||||
#define DVD_BANNER_WIDTH 96
|
#define DVD_BANNER_WIDTH 96
|
||||||
#define DVD_BANNER_HEIGHT 32
|
#define DVD_BANNER_HEIGHT 32
|
||||||
|
|
||||||
|
static std::string GetLanguageString(IVolume::ELanguage language, std::map<IVolume::ELanguage, std::string> strings)
|
||||||
|
{
|
||||||
|
auto end = strings.end();
|
||||||
|
auto it = strings.find(language);
|
||||||
|
if (it != end)
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
// English tends to be a good fallback when the requested language isn't available
|
||||||
|
if (language != IVolume::ELanguage::LANGUAGE_ENGLISH)
|
||||||
|
{
|
||||||
|
it = strings.find(IVolume::ELanguage::LANGUAGE_ENGLISH);
|
||||||
|
if (it != end)
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If English isn't available either, just pick something
|
||||||
|
if (!strings.empty())
|
||||||
|
return strings.cbegin()->second;
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -67,7 +89,9 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
||||||
else
|
else
|
||||||
m_Platform = WII_WAD;
|
m_Platform = WII_WAD;
|
||||||
|
|
||||||
m_volume_names = pVolume->GetNames();
|
m_names = pVolume->GetNames();
|
||||||
|
m_descriptions = pVolume->GetDescriptions();
|
||||||
|
m_company = pVolume->GetCompany();
|
||||||
|
|
||||||
m_Country = pVolume->GetCountry();
|
m_Country = pVolume->GetCountry();
|
||||||
m_FileSize = pVolume->GetRawSize();
|
m_FileSize = pVolume->GetRawSize();
|
||||||
|
@ -78,23 +102,8 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
||||||
m_IsDiscTwo = pVolume->IsDiscTwo();
|
m_IsDiscTwo = pVolume->IsDiscTwo();
|
||||||
m_Revision = pVolume->GetRevision();
|
m_Revision = pVolume->GetRevision();
|
||||||
|
|
||||||
// check if we can get some info from the banner file too
|
std::vector<u32> Buffer = pVolume->GetBanner(&m_ImageWidth, &m_ImageHeight);
|
||||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
u32* pData = Buffer.data();
|
||||||
|
|
||||||
if (pFileSystem != nullptr || m_Platform == WII_WAD)
|
|
||||||
{
|
|
||||||
std::unique_ptr<DiscIO::IBannerLoader> pBannerLoader(DiscIO::CreateBannerLoader(*pFileSystem, pVolume));
|
|
||||||
|
|
||||||
if (pBannerLoader != nullptr && pBannerLoader->IsValid())
|
|
||||||
{
|
|
||||||
if (m_Platform != WII_WAD)
|
|
||||||
m_banner_names = pBannerLoader->GetNames();
|
|
||||||
m_company = pBannerLoader->GetCompany();
|
|
||||||
m_descriptions = pBannerLoader->GetDescriptions();
|
|
||||||
|
|
||||||
std::vector<u32> Buffer = pBannerLoader->GetBanner(&m_ImageWidth, &m_ImageHeight);
|
|
||||||
u32* pData = &Buffer[0];
|
|
||||||
// resize vector to image size
|
|
||||||
m_pImage.resize(m_ImageWidth * m_ImageHeight * 3);
|
m_pImage.resize(m_ImageWidth * m_ImageHeight * 3);
|
||||||
|
|
||||||
for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++)
|
for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++)
|
||||||
|
@ -103,10 +112,6 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
||||||
m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8;
|
m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8;
|
||||||
m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0;
|
m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete pFileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete pVolume;
|
delete pVolume;
|
||||||
|
|
||||||
|
@ -131,7 +136,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
||||||
wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
|
wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
|
||||||
double Scale = wxTheApp->GetTopWindow()->GetContentScaleFactor();
|
double Scale = wxTheApp->GetTopWindow()->GetContentScaleFactor();
|
||||||
// Note: This uses nearest neighbor, which subjectively looks a lot
|
// Note: This uses nearest neighbor, which subjectively looks a lot
|
||||||
// better for GC banners than smooths caling.
|
// better for GC banners than smooth scaling.
|
||||||
Image.Rescale(DVD_BANNER_WIDTH * Scale, DVD_BANNER_HEIGHT * Scale);
|
Image.Rescale(DVD_BANNER_WIDTH * Scale, DVD_BANNER_HEIGHT * Scale);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
m_Bitmap = wxBitmap(Image, -1, Scale);
|
m_Bitmap = wxBitmap(Image, -1, Scale);
|
||||||
|
@ -165,10 +170,9 @@ void GameListItem::SaveToCache()
|
||||||
|
|
||||||
void GameListItem::DoState(PointerWrap &p)
|
void GameListItem::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(m_volume_names);
|
p.Do(m_names);
|
||||||
p.Do(m_company);
|
|
||||||
p.Do(m_banner_names);
|
|
||||||
p.Do(m_descriptions);
|
p.Do(m_descriptions);
|
||||||
|
p.Do(m_company);
|
||||||
p.Do(m_UniqueID);
|
p.Do(m_UniqueID);
|
||||||
p.Do(m_FileSize);
|
p.Do(m_FileSize);
|
||||||
p.Do(m_VolumeSize);
|
p.Do(m_VolumeSize);
|
||||||
|
@ -202,73 +206,43 @@ std::string GameListItem::CreateCacheFilename()
|
||||||
|
|
||||||
std::string GameListItem::GetCompany() const
|
std::string GameListItem::GetCompany() const
|
||||||
{
|
{
|
||||||
if (m_company.empty())
|
|
||||||
return "N/A";
|
|
||||||
else
|
|
||||||
return m_company;
|
return m_company;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (-1 = Japanese, 0 = English, etc)?
|
std::string GameListItem::GetDescription(IVolume::ELanguage language) const
|
||||||
std::string GameListItem::GetDescription(int _index) const
|
|
||||||
{
|
{
|
||||||
const u32 index = _index;
|
return GetLanguageString(language, m_descriptions);
|
||||||
|
|
||||||
if (index < m_descriptions.size())
|
|
||||||
return m_descriptions[index];
|
|
||||||
|
|
||||||
if (!m_descriptions.empty())
|
|
||||||
return m_descriptions[0];
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (-1 = Japanese, 0 = English, etc)?
|
std::string GameListItem::GetDescription() const
|
||||||
std::string GameListItem::GetVolumeName(int _index) const
|
|
||||||
{
|
{
|
||||||
u32 const index = _index;
|
return GetDescription(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_Platform != GAMECUBE_DISC));
|
||||||
|
|
||||||
if (index < m_volume_names.size() && !m_volume_names[index].empty())
|
|
||||||
return m_volume_names[index];
|
|
||||||
|
|
||||||
if (!m_volume_names.empty())
|
|
||||||
return m_volume_names[0];
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (-1 = Japanese, 0 = English, etc)?
|
std::string GameListItem::GetName(IVolume::ELanguage language) const
|
||||||
std::string GameListItem::GetBannerName(int _index) const
|
|
||||||
{
|
{
|
||||||
u32 const index = _index;
|
return GetLanguageString(language, m_names);
|
||||||
|
|
||||||
if (index < m_banner_names.size() && !m_banner_names[index].empty())
|
|
||||||
return m_banner_names[index];
|
|
||||||
|
|
||||||
if (!m_banner_names.empty())
|
|
||||||
return m_banner_names[0];
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (-1 = Japanese, 0 = English, etc)?
|
std::string GameListItem::GetName() const
|
||||||
std::string GameListItem::GetName(int _index) const
|
|
||||||
{
|
{
|
||||||
// Prefer name from banner, fallback to name from volume, fallback to filename
|
std::string name = GetName(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_Platform != GAMECUBE_DISC));
|
||||||
|
|
||||||
std::string name = GetBannerName(_index);
|
|
||||||
|
|
||||||
if (name.empty())
|
|
||||||
name = GetVolumeName(_index);
|
|
||||||
|
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
{
|
{
|
||||||
// No usable name, return filename (better than nothing)
|
// No usable name, return filename (better than nothing)
|
||||||
SplitPath(GetFileName(), nullptr, &name, nullptr);
|
SplitPath(GetFileName(), nullptr, &name, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<IVolume::ELanguage> GameListItem::GetLanguages() const
|
||||||
|
{
|
||||||
|
std::vector<IVolume::ELanguage> languages;
|
||||||
|
for (std::pair<IVolume::ELanguage, std::string> name : m_names)
|
||||||
|
languages.push_back(name.first);
|
||||||
|
return languages;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string GameListItem::GetWiiFSPath() const
|
const std::string GameListItem::GetWiiFSPath() const
|
||||||
{
|
{
|
||||||
DiscIO::IVolume *iso = DiscIO::CreateVolumeFromFilename(m_FileName);
|
DiscIO::IVolume *iso = DiscIO::CreateVolumeFromFilename(m_FileName);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
@ -24,11 +25,12 @@ public:
|
||||||
|
|
||||||
bool IsValid() const {return m_Valid;}
|
bool IsValid() const {return m_Valid;}
|
||||||
const std::string& GetFileName() const {return m_FileName;}
|
const std::string& GetFileName() const {return m_FileName;}
|
||||||
std::string GetBannerName(int index) const;
|
std::string GetName(IVolume::ELanguage language) const;
|
||||||
std::string GetVolumeName(int index) const;
|
std::string GetName() const;
|
||||||
std::string GetName(int index) const;
|
std::string GetDescription(IVolume::ELanguage language) const;
|
||||||
|
std::string GetDescription() const;
|
||||||
|
std::vector<IVolume::ELanguage> GetLanguages() const;
|
||||||
std::string GetCompany() const;
|
std::string GetCompany() const;
|
||||||
std::string GetDescription(int index = 0) const;
|
|
||||||
int GetRevision() const { return m_Revision; }
|
int GetRevision() const { return m_Revision; }
|
||||||
const std::string& GetUniqueID() const {return m_UniqueID;}
|
const std::string& GetUniqueID() const {return m_UniqueID;}
|
||||||
const std::string GetWiiFSPath() const;
|
const std::string GetWiiFSPath() const;
|
||||||
|
@ -57,13 +59,9 @@ public:
|
||||||
private:
|
private:
|
||||||
std::string m_FileName;
|
std::string m_FileName;
|
||||||
|
|
||||||
// TODO: eliminate this and overwrite with names from banner when available?
|
std::map<IVolume::ELanguage, std::string> m_names;
|
||||||
std::vector<std::string> m_volume_names;
|
std::map<IVolume::ELanguage, std::string> m_descriptions;
|
||||||
|
|
||||||
// Stuff from banner
|
|
||||||
std::string m_company;
|
std::string m_company;
|
||||||
std::vector<std::string> m_banner_names;
|
|
||||||
std::vector<std::string> m_descriptions;
|
|
||||||
|
|
||||||
std::string m_UniqueID;
|
std::string m_UniqueID;
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,8 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
||||||
{
|
{
|
||||||
// Load ISO data
|
// Load ISO data
|
||||||
OpenISO = DiscIO::CreateVolumeFromFilename(fileName);
|
OpenISO = DiscIO::CreateVolumeFromFilename(fileName);
|
||||||
bool IsWad = OpenISO->IsWadFile();
|
|
||||||
|
|
||||||
// TODO: Is it really necessary to use GetTitleID in case GetUniqueID fails?
|
// Is it really necessary to use GetTitleID if GetUniqueID fails?
|
||||||
game_id = OpenISO->GetUniqueID();
|
game_id = OpenISO->GetUniqueID();
|
||||||
if (game_id.empty())
|
if (game_id.empty())
|
||||||
{
|
{
|
||||||
|
@ -137,7 +136,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
||||||
|
|
||||||
bRefreshList = false;
|
bRefreshList = false;
|
||||||
|
|
||||||
CreateGUIControls(IsWad);
|
CreateGUIControls();
|
||||||
|
|
||||||
LoadGameConfig();
|
LoadGameConfig();
|
||||||
|
|
||||||
|
@ -173,33 +172,15 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
||||||
break;
|
break;
|
||||||
case DiscIO::IVolume::COUNTRY_USA:
|
case DiscIO::IVolume::COUNTRY_USA:
|
||||||
m_Country->SetValue(_("USA"));
|
m_Country->SetValue(_("USA"));
|
||||||
if (!IsWad) // For (non wad) NTSC Games, there's no multi lang
|
|
||||||
{
|
|
||||||
m_Lang->SetSelection(0);
|
|
||||||
m_Lang->Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DiscIO::IVolume::COUNTRY_JAPAN:
|
case DiscIO::IVolume::COUNTRY_JAPAN:
|
||||||
m_Country->SetValue(_("Japan"));
|
m_Country->SetValue(_("Japan"));
|
||||||
if (!IsWad) // For (non wad) NTSC Games, there's no multi lang
|
|
||||||
{
|
|
||||||
m_Lang->Insert(_("Japanese"), 0);
|
|
||||||
m_Lang->SetSelection(0);
|
|
||||||
m_Lang->Disable();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DiscIO::IVolume::COUNTRY_KOREA:
|
case DiscIO::IVolume::COUNTRY_KOREA:
|
||||||
m_Country->SetValue(_("Korea"));
|
m_Country->SetValue(_("Korea"));
|
||||||
break;
|
break;
|
||||||
case DiscIO::IVolume::COUNTRY_TAIWAN:
|
case DiscIO::IVolume::COUNTRY_TAIWAN:
|
||||||
m_Country->SetValue(_("Taiwan"));
|
m_Country->SetValue(_("Taiwan"));
|
||||||
if (!IsWad) // For (non wad) NTSC Games, there's no multi lang
|
|
||||||
{
|
|
||||||
m_Lang->Insert(_("Taiwan"), 0);
|
|
||||||
m_Lang->SetSelection(0);
|
|
||||||
m_Lang->Disable();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DiscIO::IVolume::COUNTRY_WORLD:
|
case DiscIO::IVolume::COUNTRY_WORLD:
|
||||||
m_Country->SetValue(_("World"));
|
m_Country->SetValue(_("World"));
|
||||||
|
@ -210,27 +191,14 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OpenISO->IsWiiDisc()) // Only one language with Wii banners
|
|
||||||
{
|
|
||||||
m_Lang->SetSelection(0);
|
|
||||||
m_Lang->Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString temp = "0x" + StrToWxStr(OpenISO->GetMakerID());
|
wxString temp = "0x" + StrToWxStr(OpenISO->GetMakerID());
|
||||||
m_MakerID->SetValue(temp);
|
m_MakerID->SetValue(temp);
|
||||||
m_Revision->SetValue(wxString::Format("%u", OpenISO->GetRevision()));
|
m_Revision->SetValue(wxString::Format("%u", OpenISO->GetRevision()));
|
||||||
m_Date->SetValue(StrToWxStr(OpenISO->GetApploaderDate()));
|
m_Date->SetValue(StrToWxStr(OpenISO->GetApploaderDate()));
|
||||||
m_FST->SetValue(wxString::Format("%u", OpenISO->GetFSTSize()));
|
m_FST->SetValue(wxString::Format("%u", OpenISO->GetFSTSize()));
|
||||||
|
|
||||||
// Here we set all the info to be shown (be it SJIS or Ascii) + we set the window title
|
// Here we set all the info to be shown + we set the window title
|
||||||
if (!IsWad)
|
ChangeBannerDetails(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(OpenISO->IsWadFile() || OpenISO->IsWiiDisc()));
|
||||||
{
|
|
||||||
ChangeBannerDetails(SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ChangeBannerDetails(SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG"));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Banner->SetBitmap(OpenGameListItem->GetBitmap());
|
m_Banner->SetBitmap(OpenGameListItem->GetBitmap());
|
||||||
m_Banner->Bind(wxEVT_RIGHT_DOWN, &CISOProperties::RightClickOnBanner, this);
|
m_Banner->Bind(wxEVT_RIGHT_DOWN, &CISOProperties::RightClickOnBanner, this);
|
||||||
|
@ -351,7 +319,7 @@ long CISOProperties::GetElementStyle(const char* section, const char* key)
|
||||||
return wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER;
|
return wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CISOProperties::CreateGUIControls(bool IsWad)
|
void CISOProperties::CreateGUIControls()
|
||||||
{
|
{
|
||||||
wxButton* const EditConfig = new wxButton(this, ID_EDITCONFIG, _("Edit Config"));
|
wxButton* const EditConfig = new wxButton(this, ID_EDITCONFIG, _("Edit Config"));
|
||||||
EditConfig->SetToolTip(_("This will let you manually edit the INI config file."));
|
EditConfig->SetToolTip(_("This will let you manually edit the INI config file."));
|
||||||
|
@ -534,24 +502,58 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
||||||
m_MD5SumCompute = new wxButton(m_Information, ID_MD5SUMCOMPUTE, _("Compute"));
|
m_MD5SumCompute = new wxButton(m_Information, ID_MD5SUMCOMPUTE, _("Compute"));
|
||||||
|
|
||||||
wxStaticText* const m_LangText = new wxStaticText(m_Information, wxID_ANY, _("Show Language:"));
|
wxStaticText* const m_LangText = new wxStaticText(m_Information, wxID_ANY, _("Show Language:"));
|
||||||
arrayStringFor_Lang.Add(_("English"));
|
|
||||||
arrayStringFor_Lang.Add(_("German"));
|
|
||||||
arrayStringFor_Lang.Add(_("French"));
|
|
||||||
arrayStringFor_Lang.Add(_("Spanish"));
|
|
||||||
arrayStringFor_Lang.Add(_("Italian"));
|
|
||||||
arrayStringFor_Lang.Add(_("Dutch"));
|
|
||||||
int language = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage;
|
|
||||||
if (IsWad)
|
|
||||||
{
|
|
||||||
arrayStringFor_Lang.Insert(_("Japanese"), 0);
|
|
||||||
arrayStringFor_Lang.Add(_("Simplified Chinese"));
|
|
||||||
arrayStringFor_Lang.Add(_("Traditional Chinese"));
|
|
||||||
arrayStringFor_Lang.Add(_("Korean"));
|
|
||||||
|
|
||||||
language = SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.LNG");
|
IVolume::ELanguage preferred_language = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(OpenISO->IsWadFile() || OpenISO->IsWiiDisc());
|
||||||
|
|
||||||
|
std::vector<IVolume::ELanguage> languages = OpenGameListItem->GetLanguages();
|
||||||
|
int preferred_language_index = 0;
|
||||||
|
for (size_t i = 0; i < languages.size(); ++i)
|
||||||
|
{
|
||||||
|
if (languages[i] == preferred_language)
|
||||||
|
preferred_language_index = i;
|
||||||
|
|
||||||
|
switch (languages[i])
|
||||||
|
{
|
||||||
|
case IVolume::LANGUAGE_JAPANESE:
|
||||||
|
arrayStringFor_Lang.Add(_("Japanese"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_ENGLISH:
|
||||||
|
arrayStringFor_Lang.Add(_("English"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_GERMAN:
|
||||||
|
arrayStringFor_Lang.Add(_("German"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_FRENCH:
|
||||||
|
arrayStringFor_Lang.Add(_("French"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_SPANISH:
|
||||||
|
arrayStringFor_Lang.Add(_("Spanish"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_ITALIAN:
|
||||||
|
arrayStringFor_Lang.Add(_("Italian"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_DUTCH:
|
||||||
|
arrayStringFor_Lang.Add(_("Dutch"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_SIMPLIFIED_CHINESE:
|
||||||
|
arrayStringFor_Lang.Add(_("Simplified Chinese"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_TRADITIONAL_CHINESE:
|
||||||
|
arrayStringFor_Lang.Add(_("Traditional Chinese"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_KOREAN:
|
||||||
|
arrayStringFor_Lang.Add(_("Korean"));
|
||||||
|
break;
|
||||||
|
case IVolume::LANGUAGE_UNKNOWN:
|
||||||
|
default:
|
||||||
|
arrayStringFor_Lang.Add(_("Unknown"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_Lang = new wxChoice(m_Information, ID_LANG, wxDefaultPosition, wxDefaultSize, arrayStringFor_Lang);
|
m_Lang = new wxChoice(m_Information, ID_LANG, wxDefaultPosition, wxDefaultSize, arrayStringFor_Lang);
|
||||||
m_Lang->SetSelection(language);
|
m_Lang->SetSelection(preferred_language_index);
|
||||||
|
if (arrayStringFor_Lang.size() <= 1)
|
||||||
|
m_Lang->Disable();
|
||||||
|
|
||||||
wxStaticText* const m_ShortText = new wxStaticText(m_Information, wxID_ANY, _("Short Name:"));
|
wxStaticText* const m_ShortText = new wxStaticText(m_Information, wxID_ANY, _("Short Name:"));
|
||||||
m_ShortName = new wxTextCtrl(m_Information, ID_SHORTNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
|
m_ShortName = new wxTextCtrl(m_Information, ID_SHORTNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
|
||||||
|
@ -611,7 +613,7 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
||||||
sInfoPage->Add(sbBannerDetails, 0, wxEXPAND|wxALL, 5);
|
sInfoPage->Add(sbBannerDetails, 0, wxEXPAND|wxALL, 5);
|
||||||
m_Information->SetSizer(sInfoPage);
|
m_Information->SetSizer(sInfoPage);
|
||||||
|
|
||||||
if (!IsWad)
|
if (!OpenISO->IsWadFile())
|
||||||
{
|
{
|
||||||
wxPanel* const m_Filesystem = new wxPanel(m_Notebook, ID_FILESYSTEM);
|
wxPanel* const m_Filesystem = new wxPanel(m_Notebook, ID_FILESYSTEM);
|
||||||
m_Notebook->AddPage(m_Filesystem, _("Filesystem"));
|
m_Notebook->AddPage(m_Filesystem, _("Filesystem"));
|
||||||
|
@ -1490,13 +1492,13 @@ void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event)
|
||||||
|
|
||||||
void CISOProperties::OnChangeBannerLang(wxCommandEvent& event)
|
void CISOProperties::OnChangeBannerLang(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
ChangeBannerDetails(event.GetSelection());
|
ChangeBannerDetails(OpenGameListItem->GetLanguages()[event.GetSelection()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CISOProperties::ChangeBannerDetails(int lang)
|
void CISOProperties::ChangeBannerDetails(IVolume::ELanguage language)
|
||||||
{
|
{
|
||||||
wxString const shortName = StrToWxStr(OpenGameListItem->GetName(lang));
|
wxString const shortName = StrToWxStr(OpenGameListItem->GetName(language));
|
||||||
wxString const comment = StrToWxStr(OpenGameListItem->GetDescription(lang));
|
wxString const comment = StrToWxStr(OpenGameListItem->GetDescription(language));
|
||||||
wxString const maker = StrToWxStr(OpenGameListItem->GetCompany());
|
wxString const maker = StrToWxStr(OpenGameListItem->GetCompany());
|
||||||
|
|
||||||
// Updates the information shown in the window
|
// Updates the information shown in the window
|
||||||
|
|
|
@ -197,7 +197,7 @@ private:
|
||||||
|
|
||||||
void LaunchExternalEditor(const std::string& filename);
|
void LaunchExternalEditor(const std::string& filename);
|
||||||
|
|
||||||
void CreateGUIControls(bool);
|
void CreateGUIControls();
|
||||||
void OnClose(wxCloseEvent& event);
|
void OnClose(wxCloseEvent& event);
|
||||||
void OnCloseClick(wxCommandEvent& event);
|
void OnCloseClick(wxCommandEvent& event);
|
||||||
void OnEditConfig(wxCommandEvent& event);
|
void OnEditConfig(wxCommandEvent& event);
|
||||||
|
@ -242,7 +242,7 @@ private:
|
||||||
void PatchList_Load();
|
void PatchList_Load();
|
||||||
void PatchList_Save();
|
void PatchList_Save();
|
||||||
void ActionReplayList_Save();
|
void ActionReplayList_Save();
|
||||||
void ChangeBannerDetails(int lang);
|
void ChangeBannerDetails(IVolume::ELanguage language);
|
||||||
|
|
||||||
long GetElementStyle(const char* section, const char* key);
|
long GetElementStyle(const char* section, const char* key);
|
||||||
void SetCheckboxValueFromGameini(const char* section, const char* key, wxCheckBox* checkbox);
|
void SetCheckboxValueFromGameini(const char* section, const char* key, wxCheckBox* checkbox);
|
||||||
|
|
|
@ -37,9 +37,6 @@
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
|
||||||
// Banner loading
|
|
||||||
#include "DiscIO/BannerLoader.h"
|
|
||||||
#include "DiscIO/Filesystem.h"
|
|
||||||
#include "DiscIO/VolumeCreator.h"
|
#include "DiscIO/VolumeCreator.h"
|
||||||
|
|
||||||
#include "UICommon/UICommon.h"
|
#include "UICommon/UICommon.h"
|
||||||
|
@ -114,8 +111,8 @@ static bool MsgAlert(const char* caption, const char* text, bool /*yes_no*/, int
|
||||||
|
|
||||||
#define DVD_BANNER_WIDTH 96
|
#define DVD_BANNER_WIDTH 96
|
||||||
#define DVD_BANNER_HEIGHT 32
|
#define DVD_BANNER_HEIGHT 32
|
||||||
std::vector<std::string> m_volume_names;
|
std::map<DiscIO::IVolume::ELanguage, std::string> m_names;
|
||||||
std::vector<std::string> m_names;
|
bool m_is_wii_title;
|
||||||
|
|
||||||
static inline u32 Average32(u32 a, u32 b) {
|
static inline u32 Average32(u32 a, u32 b) {
|
||||||
return ((a >> 1) & 0x7f7f7f7f) + ((b >> 1) & 0x7f7f7f7f);
|
return ((a >> 1) & 0x7f7f7f7f) + ((b >> 1) & 0x7f7f7f7f);
|
||||||
|
@ -130,34 +127,20 @@ static inline u32 GetPixel(u32 *buffer, unsigned int x, unsigned int y) {
|
||||||
|
|
||||||
static bool LoadBanner(std::string filename, u32 *Banner)
|
static bool LoadBanner(std::string filename, u32 *Banner)
|
||||||
{
|
{
|
||||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename);
|
std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(filename));
|
||||||
|
|
||||||
if (pVolume != nullptr)
|
if (pVolume != nullptr)
|
||||||
{
|
{
|
||||||
bool bIsWad = false;
|
m_names = pVolume->GetNames();
|
||||||
if (DiscIO::IsVolumeWadFile(pVolume))
|
m_is_wii_title = pVolume->IsWiiDisc() || pVolume->IsWadFile();
|
||||||
bIsWad = true;
|
|
||||||
|
|
||||||
m_volume_names = pVolume->GetNames();
|
|
||||||
|
|
||||||
// check if we can get some info from the banner file too
|
|
||||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
|
||||||
|
|
||||||
if (pFileSystem != nullptr || bIsWad)
|
|
||||||
{
|
|
||||||
DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem, pVolume);
|
|
||||||
|
|
||||||
if (pBannerLoader != nullptr)
|
|
||||||
if (pBannerLoader->IsValid())
|
|
||||||
{
|
|
||||||
m_names = pBannerLoader->GetNames();
|
|
||||||
int Width, Height;
|
int Width, Height;
|
||||||
std::vector<u32> BannerVec = pBannerLoader->GetBanner(&Width, &Height);
|
std::vector<u32> BannerVec = pVolume->GetBanner(&Width, &Height);
|
||||||
// This code (along with above inlines) is moved from
|
// This code (along with above inlines) is moved from
|
||||||
// elsewhere. Someone who knows anything about Android
|
// elsewhere. Someone who knows anything about Android
|
||||||
// please get rid of it and use proper high-resolution
|
// please get rid of it and use proper high-resolution
|
||||||
// images.
|
// images.
|
||||||
if (Height == 64)
|
if (Height == 64 && Width == 192)
|
||||||
{
|
{
|
||||||
u32* Buffer = &BannerVec[0];
|
u32* Buffer = &BannerVec[0];
|
||||||
for (int y = 0; y < 32; y++)
|
for (int y = 0; y < 32; y++)
|
||||||
|
@ -171,13 +154,12 @@ static bool LoadBanner(std::string filename, u32 *Banner)
|
||||||
Banner[y * 96 + x] = Average32(GetPixel(Buffer, x*2, y*2), surround);
|
Banner[y * 96 + x] = Average32(GetPixel(Buffer, x*2, y*2), surround);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(Banner, &BannerVec[0], 96 * 32 * 4);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (Height == 32 && Width == 96)
|
||||||
|
{
|
||||||
|
memcpy(Banner, &BannerVec[0], 96 * 32 * 4);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,15 +168,28 @@ static bool LoadBanner(std::string filename, u32 *Banner)
|
||||||
|
|
||||||
static std::string GetName(std::string filename)
|
static std::string GetName(std::string filename)
|
||||||
{
|
{
|
||||||
if (!m_names.empty())
|
DiscIO::IVolume::ELanguage language = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_is_wii_title);
|
||||||
return m_names[0];
|
|
||||||
|
auto end = m_names.end();
|
||||||
|
auto it = m_names.find(language);
|
||||||
|
if (it != end)
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
// English tends to be a good fallback when the requested language isn't available
|
||||||
|
if (language != IVolume::ELanguage::LANGUAGE_ENGLISH)
|
||||||
|
{
|
||||||
|
it = m_names.find(IVolume::ELanguage::LANGUAGE_ENGLISH);
|
||||||
|
if (it != end)
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If English isn't available either, just pick something
|
||||||
|
if (!m_names.empty())
|
||||||
|
return m_names.cbegin()->second;
|
||||||
|
|
||||||
if (!m_volume_names.empty())
|
|
||||||
return m_volume_names[0];
|
|
||||||
// No usable name, return filename (better than nothing)
|
// No usable name, return filename (better than nothing)
|
||||||
std::string name;
|
std::string name;
|
||||||
SplitPath(filename, nullptr, &name, nullptr);
|
SplitPath(filename, nullptr, &name, nullptr);
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +271,6 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetTitle(
|
||||||
std::string file = GetJString(env, jFile);
|
std::string file = GetJString(env, jFile);
|
||||||
std::string name = GetName(file);
|
std::string name = GetName(file);
|
||||||
m_names.clear();
|
m_names.clear();
|
||||||
m_volume_names.clear();
|
|
||||||
|
|
||||||
return env->NewStringUTF(name.c_str());
|
return env->NewStringUTF(name.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ static wxString FailureReasonStringForHostLabel(int reason)
|
||||||
static std::string BuildGameName(const GameListItem& game)
|
static std::string BuildGameName(const GameListItem& game)
|
||||||
{
|
{
|
||||||
// Lang needs to be consistent
|
// Lang needs to be consistent
|
||||||
auto const lang = 0;
|
IVolume::ELanguage const lang = IVolume::LANGUAGE_ENGLISH;
|
||||||
|
|
||||||
std::string name(game.GetName(lang));
|
std::string name(game.GetName(lang));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue