mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #2286 from JosJuice/wii-opening-bnr
Read opening.bnr to get names from Wii discs
This commit is contained in:
@@ -304,7 +304,7 @@ void SConfig::SaveGameListSettings(IniFile& ini)
|
||||
|
||||
gamelist->Set("ColumnPlatform", m_showSystemColumn);
|
||||
gamelist->Set("ColumnBanner", m_showBannerColumn);
|
||||
gamelist->Set("ColumnNotes", m_showNotesColumn);
|
||||
gamelist->Set("ColumnNotes", m_showMakerColumn);
|
||||
gamelist->Set("ColumnID", m_showIDColumn);
|
||||
gamelist->Set("ColumnRegion", m_showRegionColumn);
|
||||
gamelist->Set("ColumnSize", m_showSizeColumn);
|
||||
@@ -557,7 +557,7 @@ void SConfig::LoadGameListSettings(IniFile& ini)
|
||||
// Gamelist columns toggles
|
||||
gamelist->Get("ColumnPlatform", &m_showSystemColumn, 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("ColumnRegion", &m_showRegionColumn, true);
|
||||
gamelist->Get("ColumnSize", &m_showSizeColumn, true);
|
||||
|
||||
@@ -84,7 +84,7 @@ struct SConfig : NonCopyable
|
||||
// Game list column toggles
|
||||
bool m_showSystemColumn;
|
||||
bool m_showBannerColumn;
|
||||
bool m_showNotesColumn;
|
||||
bool m_showMakerColumn;
|
||||
bool m_showIDColumn;
|
||||
bool m_showRegionColumn;
|
||||
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
|
||||
{
|
||||
return LoadDefaultGameIni(GetUniqueID(), m_revision);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "Common/IniFile.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
enum Hotkey
|
||||
{
|
||||
@@ -248,6 +249,7 @@ struct SCoreStartupParameter
|
||||
bool AutoSetup(EBootBS2 _BootBS2);
|
||||
const std::string &GetUniqueID() const { return m_strUniqueID; }
|
||||
void CheckMemcardPath(std::string& memcardPath, std::string gameRegion, bool isSlotA);
|
||||
DiscIO::IVolume::ELanguage GetCurrentLanguage(bool wii) const;
|
||||
|
||||
IniFile LoadDefaultGameIni() 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
|
||||
BannerLoaderGC.cpp
|
||||
BannerLoaderWii.cpp
|
||||
Blob.cpp
|
||||
set(SRCS Blob.cpp
|
||||
CISOBlob.cpp
|
||||
WbfsBlob.cpp
|
||||
CompressedBlob.cpp
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BannerLoader.cpp" />
|
||||
<ClCompile Include="BannerLoaderGC.cpp" />
|
||||
<ClCompile Include="BannerLoaderWii.cpp" />
|
||||
<ClCompile Include="Blob.cpp" />
|
||||
<ClCompile Include="CISOBlob.cpp" />
|
||||
<ClCompile Include="CompressedBlob.cpp" />
|
||||
@@ -58,9 +55,6 @@
|
||||
<ClCompile Include="WiiWad.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BannerLoader.h" />
|
||||
<ClInclude Include="BannerLoaderGC.h" />
|
||||
<ClInclude Include="BannerLoaderWii.h" />
|
||||
<ClInclude Include="Blob.h" />
|
||||
<ClInclude Include="CISOBlob.h" />
|
||||
<ClInclude Include="CompressedBlob.h" />
|
||||
|
||||
@@ -24,15 +24,6 @@
|
||||
<ClCompile Include="DiscScrubber.cpp">
|
||||
<Filter>DiscScrubber</Filter>
|
||||
</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">
|
||||
<Filter>FileSystem</Filter>
|
||||
</ClCompile>
|
||||
@@ -89,15 +80,6 @@
|
||||
<ClInclude Include="DiscScrubber.h">
|
||||
<Filter>DiscScrubber</Filter>
|
||||
</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">
|
||||
<Filter>FileSystem</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -63,7 +63,7 @@ const std::string CFileSystemGCWii::GetFileName(u64 _Address)
|
||||
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)
|
||||
InitFileSystem();
|
||||
@@ -72,14 +72,16 @@ u64 CFileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size
|
||||
if (pFileInfo == nullptr)
|
||||
return 0;
|
||||
|
||||
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
||||
if (_OffsetInFile >= pFileInfo->m_FileSize)
|
||||
return 0;
|
||||
|
||||
DEBUG_LOG(DISCIO, "Filename: %s. Offset: %" PRIx64 ". Size: %" PRIx64, _rFullPath.c_str(),
|
||||
pFileInfo->m_Offset, pFileInfo->m_FileSize);
|
||||
u64 read_length = std::min(_MaxBufferSize, pFileInfo->m_FileSize - _OffsetInFile);
|
||||
|
||||
m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer, m_Wii);
|
||||
return pFileInfo->m_FileSize;
|
||||
DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 " Size: %" PRIx64,
|
||||
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)
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
virtual u64 GetFileSize(const std::string& _rFullPath) override;
|
||||
virtual size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) 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 ExportApploader(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 size_t GetFileList(std::vector<const SFileInfo *> &_rFilenames) = 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 ExportApploader(const std::string& _rExportFolder) const = 0;
|
||||
virtual bool ExportDOL(const std::string& _rExportFolder) const = 0;
|
||||
|
||||
+69
-24
@@ -4,18 +4,57 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class IVolume
|
||||
{
|
||||
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() {}
|
||||
virtual ~IVolume() {}
|
||||
|
||||
@@ -36,10 +75,12 @@ public:
|
||||
}
|
||||
virtual std::string GetUniqueID() const = 0;
|
||||
virtual std::string GetMakerID() const = 0;
|
||||
virtual int GetRevision() const { return 0; }
|
||||
// TODO: eliminate?
|
||||
virtual std::string GetName() const;
|
||||
virtual std::vector<std::string> GetNames() const = 0;
|
||||
virtual int GetRevision() const = 0;
|
||||
virtual std::string GetName() const = 0;
|
||||
virtual std::map<ELanguage, 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 std::string GetApploaderDate() const = 0;
|
||||
|
||||
@@ -50,31 +91,35 @@ public:
|
||||
virtual bool CheckIntegrity() const { 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 u64 GetSize() const = 0;
|
||||
|
||||
// Size on disc (compressed size)
|
||||
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
|
||||
|
||||
@@ -2,16 +2,83 @@
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/ColorUtil.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
// Increment CACHE_REVISION if the code below is modified (ISOFile.cpp & GameFile.cpp)
|
||||
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)
|
||||
{
|
||||
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 <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
@@ -183,9 +182,22 @@ std::string CVolumeDirectory::GetMakerID() const
|
||||
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)
|
||||
|
||||
@@ -39,7 +39,9 @@ public:
|
||||
|
||||
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&);
|
||||
|
||||
u32 GetFSTSize() const override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user