summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2013-03-03 19:56:36 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2013-03-03 19:56:36 -0600
commitfcf87f6c53fd26b4dcbba5151185f3c4f4d4bd1d (patch)
tree08fd3277db552867f251bed449400f68387ac6f6 /Source/Core/DiscIO
parentcedfa452b4497590f828306b42b1e7c24915fd58 (diff)
parent814c2ffdfd213dfa78078471d298e2657b7e14e9 (diff)
Merge branch 'windows-unicode'
Fixed unicode filename handling on Windows. Made all significant projects build with "Unicode" option on Windows. Fixed unicode string handling in GUI code on all OSes. From now on: std::string == UTF-8. Fixed issue 4111. Fixed issue 5178. Fixed issue 5980.
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj4
-rw-r--r--Source/Core/DiscIO/Src/BannerLoader.cpp182
-rw-r--r--Source/Core/DiscIO/Src/BannerLoader.h24
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderGC.cpp143
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderGC.h36
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderWii.cpp76
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderWii.h13
-rw-r--r--Source/Core/DiscIO/Src/DriveBlob.cpp8
-rw-r--r--Source/Core/DiscIO/Src/FileSystemGCWii.cpp32
-rw-r--r--Source/Core/DiscIO/Src/FileSystemGCWii.h6
-rw-r--r--Source/Core/DiscIO/Src/Volume.h6
-rw-r--r--Source/Core/DiscIO/Src/VolumeCommon.cpp10
-rw-r--r--Source/Core/DiscIO/Src/VolumeDirectory.cpp5
-rw-r--r--Source/Core/DiscIO/Src/VolumeDirectory.h2
-rw-r--r--Source/Core/DiscIO/Src/VolumeGC.cpp21
-rw-r--r--Source/Core/DiscIO/Src/VolumeGC.h6
-rw-r--r--Source/Core/DiscIO/Src/VolumeWad.cpp81
-rw-r--r--Source/Core/DiscIO/Src/VolumeWad.h3
-rw-r--r--Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp21
-rw-r--r--Source/Core/DiscIO/Src/VolumeWiiCrypted.h2
20 files changed, 218 insertions, 463 deletions
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj
index 6dd24ddd44..722aae2040 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj
+++ b/Source/Core/DiscIO/DiscIO.vcxproj
@@ -44,7 +44,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -54,7 +54,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp
index 2350896c9c..d38c7e9ea4 100644
--- a/Source/Core/DiscIO/Src/BannerLoader.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoader.cpp
@@ -22,186 +22,8 @@
#include "VolumeCreator.h"
#include "FileUtil.h"
-// HyperIris: dunno if this suitable, may be need move.
-#ifdef _WIN32
-#include <Windows.h>
-#else
-#include <sys/param.h>
-#ifndef ANDROID
-#include <iconv.h>
-#endif
-#include <errno.h>
-#endif
-
-#ifndef ICONV_CONST
-#if defined __FreeBSD__ || __NetBSD__
-#define ICONV_CONST const
-#else
-#define ICONV_CONST
-#endif
-#endif
-
namespace DiscIO
{
-void IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src)
-{
- static bool bValidChars[256];
- static bool bInitialized = false;
-
- if (!bInitialized)
- {
- for (int i = 0; i < 0x20; i++)
- {
- bValidChars[i] = false;
- }
-
- // generate valid chars
- for (int i = 0x20; i < 256; i++)
- {
- bValidChars[i] = true;
- }
-
- bValidChars[0x0a] = true;
- //bValidChars[0xa9] = true;
- //bValidChars[0xe9] = true;
-
- bInitialized = true;
- }
-
- char destBuffer[2048] = {0};
- char* dest = destBuffer;
- const char* src = _src;
-
- // copy the string and check for "unknown" characters
- while (*src != 0x00)
- {
- u8 c = *src;
-
- if (c == 0x0a){c = 0x20;}
-
- if (bValidChars[c] == false)
- {
- src++;
- continue;
- }
-
- *dest = c;
- dest++;
- src++;
- }
-
- // finalize the string
- *dest = 0x00;
-
- _rDestination = destBuffer;
-}
-
-bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16* _src, int length )
-{
- bool returnCode = false;
-#ifdef WIN32
- if (_src)
- {
- u16* buffer = new u16[length];
- if (buffer)
- {
- memcpy(buffer, _src, sizeof(u16)*length);
- for (int i = 0; i < length; i++)
- {
- buffer[i] = swap16(buffer[i]);
- }
-
- u32 ansiNameSize = WideCharToMultiByte(932, 0,
- (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer),
- NULL, NULL, NULL, NULL);
- if (ansiNameSize > 0)
- {
- char* pAnsiStrBuffer = new char[ansiNameSize + 1];
- if (pAnsiStrBuffer)
- {
- memset(pAnsiStrBuffer, 0, (ansiNameSize + 1) * sizeof(char));
- if (WideCharToMultiByte(932, 0,
- (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer),
- pAnsiStrBuffer, ansiNameSize, NULL, NULL))
- {
- _rDestination = pAnsiStrBuffer;
- returnCode = true;
- }
- delete[] pAnsiStrBuffer;
- }
- }
- delete[] buffer;
- }
- }
-#else
-#ifdef ANDROID
- return false;
-#else
- if (_src)
- {
- iconv_t conv_desc = iconv_open("UTF-8", "CP932");
- if (conv_desc == (iconv_t) -1)
- {
- // Initialization failure.
- if (errno == EINVAL)
- {
- ERROR_LOG(DISCIO, "Conversion from CP932 to UTF-8 is not supported.");
- }
- else
- {
- ERROR_LOG(DISCIO, "Iconv initialization failure: %s\n", strerror (errno));
- }
- return false;
- }
-
- char* src_buffer = new char[length];
- for (int i = 0; i < length; i++)
- src_buffer[i] = swap16(_src[i]);
-
- size_t inbytes = sizeof(char) * length;
- size_t outbytes = 2 * inbytes;
- char* utf8_buffer = new char[outbytes + 1];
- memset(utf8_buffer, 0, (outbytes + 1) * sizeof(char));
-
- // Save the buffer locations because iconv increments them
- char* utf8_buffer_start = utf8_buffer;
- char* src_buffer_start = src_buffer;
-
- size_t iconv_size = iconv(conv_desc,
- (ICONV_CONST char**)&src_buffer, &inbytes,
- &utf8_buffer, &outbytes);
-
- // Handle failures
- if (iconv_size == (size_t) -1)
- {
- ERROR_LOG(DISCIO, "iconv failed.");
- switch (errno) {
- case EILSEQ:
- ERROR_LOG(DISCIO, "Invalid multibyte sequence.");
- break;
- case EINVAL:
- ERROR_LOG(DISCIO, "Incomplete multibyte sequence.");
- break;
- case E2BIG:
- ERROR_LOG(DISCIO, "Insufficient space allocated for output buffer.");
- break;
- default:
- ERROR_LOG(DISCIO, "Error: %s.", strerror(errno));
- }
- }
- else
- {
- _rDestination = utf8_buffer_start;
- returnCode = true;
- }
- delete[] utf8_buffer_start;
- delete[] src_buffer_start;
- iconv_close(conv_desc);
- }
-#endif
-#endif
- return returnCode;
-}
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume)
{
@@ -209,9 +31,9 @@ IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVo
{
return new CBannerLoaderWii(pVolume);
}
- if (_rFileSystem.IsValid())
+ if (_rFileSystem.IsValid())
{
- return new CBannerLoaderGC(_rFileSystem);
+ return new CBannerLoaderGC(_rFileSystem, pVolume);
}
return NULL;
diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h
index 1fe48dd364..b30ee17a46 100644
--- a/Source/Core/DiscIO/Src/BannerLoader.h
+++ b/Source/Core/DiscIO/Src/BannerLoader.h
@@ -18,6 +18,9 @@
#ifndef _BANNER_LOADER_H_
#define _BANNER_LOADER_H_
+#include <vector>
+#include <string>
+
#include "Filesystem.h"
namespace DiscIO
@@ -38,24 +41,9 @@ class IBannerLoader
virtual bool GetBanner(u32* _pBannerImage) = 0;
- virtual bool GetName(std::string* _rName) = 0;
- virtual bool GetName(std::vector<std::wstring>& _rNames) {return false;};
- virtual bool GetCompany(std::string& _rCompany) = 0;
-
- virtual bool GetDescription(std::string* _rDescription) = 0;
- virtual bool GetDescription(std::wstring& _rDescription) {return false;};
-
-
- protected:
-
- void CopyToStringAndCheck(std::string& _rDestination, const char* _src);
-
- bool CopyBeUnicodeToString(std::string& _rDestination, const u16* _src, int length);
- private:
- u16 swap16(u16 data)
- {
- return ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
- }
+ virtual std::vector<std::string> GetNames() = 0;
+ virtual std::string GetCompany() = 0;
+ virtual std::vector<std::string> GetDescriptions() = 0;
};
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume);
diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
index bf9f634ff8..d8ae259b16 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
@@ -23,13 +23,14 @@
namespace DiscIO
{
-CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem)
- : m_pBannerFile(NULL),
- m_IsValid(false)
+CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume)
+ : m_pBannerFile(NULL)
+ , m_IsValid(false)
+ , m_country(volume->GetCountry())
{
// load the opening.bnr
size_t FileSize = (size_t) _rFileSystem.GetFileSize("opening.bnr");
- if (FileSize == sizeof(DVDBanner) || FileSize == sizeof(DVDBanner2))
+ if (FileSize == BNR1_SIZE || FileSize == BNR2_SIZE)
{
m_pBannerFile = new u8[FileSize];
if (m_pBannerFile)
@@ -62,7 +63,6 @@ bool CBannerLoaderGC::IsValid()
return m_IsValid;
}
-
bool CBannerLoaderGC::GetBanner(u32* _pBannerImage)
{
if (!IsValid())
@@ -70,132 +70,111 @@ bool CBannerLoaderGC::GetBanner(u32* _pBannerImage)
return false;
}
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+ auto const pBanner = (DVDBanner*)m_pBannerFile;
decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
return true;
}
-bool CBannerLoaderGC::GetName(std::string _rName[])
+std::vector<std::string> CBannerLoaderGC::GetNames()
{
- bool returnCode = false;
+ std::vector<std::string> names;
if (!IsValid())
{
- return false;
+ return names;
}
+ u32 name_count = 0;
+
// find Banner type
switch (m_BNRType)
{
case CBannerLoaderGC::BANNER_BNR1:
- {
- DVDBanner* pBanner = (DVDBanner*)m_pBannerFile;
- char tempBuffer[65] = {0};
- if (pBanner->comment.longTitle[0])
- {
- memcpy(tempBuffer, pBanner->comment.longTitle, 64);
- }
- else
- {
- memcpy(tempBuffer, pBanner->comment.shortTitle, 32);
- }
- for (int i = 0; i < 6; i++)
- {
- CopyToStringAndCheck(_rName[i], tempBuffer);
- }
- returnCode = true;
- }
+ name_count = 1;
break;
+
case CBannerLoaderGC::BANNER_BNR2:
- {
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+ name_count = 6;
+ break;
- for (int i = 0; i < 6; i++)
- {
- char tempBuffer[65] = {0};
- if (pBanner->comment[i].longTitle[0])
- {
- memcpy(tempBuffer, pBanner->comment[i].longTitle, 64);
- }
- else
- {
- memcpy(tempBuffer, pBanner->comment[i].shortTitle, 32);
- }
- CopyToStringAndCheck(_rName[i], tempBuffer);
- }
+ default:
+ break;
+ }
- returnCode = true;
+ 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));
}
- break;
- default:
- break;
}
- return returnCode;
+ return names;
}
-bool CBannerLoaderGC::GetCompany(std::string& _rCompany)
+std::string CBannerLoaderGC::GetCompany()
{
- _rCompany = "N/A";
+ std::string company;
- if (!IsValid())
+ if (IsValid())
{
- return(false);
+ auto const pBanner = (DVDBanner*)m_pBannerFile;
+ auto& data = pBanner->comment[0].shortMaker;
+ company = GetDecodedString(data);
}
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
-
- CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker);
-
- return true;
+ return company;
}
-bool CBannerLoaderGC::GetDescription(std::string* _rDescription)
+std::vector<std::string> CBannerLoaderGC::GetDescriptions()
{
- bool returnCode = false;
+ std::vector<std::string> descriptions;
if (!IsValid())
{
- return false;
+ return descriptions;
}
+ u32 desc_count = 0;
+
// find Banner type
switch (m_BNRType)
{
case CBannerLoaderGC::BANNER_BNR1:
- {
- DVDBanner* pBanner = (DVDBanner*)m_pBannerFile;
- char tempBuffer[129] = {0};
- memcpy(tempBuffer, pBanner->comment.comment, 128);
- for (int i = 0; i < 6; i++)
- {
- CopyToStringAndCheck(_rDescription[i], tempBuffer);
- }
- returnCode = true;
- }
+ desc_count = 1;
break;
- case CBannerLoaderGC::BANNER_BNR2:
- {
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
- for (int i = 0; i< 6; i++)
- {
- char tempBuffer[129] = {0};
- memcpy(tempBuffer, pBanner->comment[i].comment, 128);
- CopyToStringAndCheck(_rDescription[i], tempBuffer);
- }
- returnCode = true;
- }
+ case CBannerLoaderGC::BANNER_BNR2:
+ desc_count = 6;
break;
+
default:
break;
}
- return returnCode;
+
+ 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;
}
@@ -223,13 +202,17 @@ CBannerLoaderGC::BANNER_TYPE CBannerLoaderGC::getBannerType()
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
diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h
index 0527c721c1..8b14a45d43 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderGC.h
+++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h
@@ -19,6 +19,8 @@
#define _BANNER_LOADER_GC_H_
#include "BannerLoader.h"
+#include "VolumeGC.h"
+#include "StringUtil.h"
namespace DiscIO
{
@@ -26,15 +28,16 @@ class CBannerLoaderGC
: public IBannerLoader
{
public:
- CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem);
+ CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume);
virtual ~CBannerLoaderGC();
virtual bool IsValid();
virtual bool GetBanner(u32* _pBannerImage);
- virtual bool GetName(std::string* _rName);
- virtual bool GetCompany(std::string& _rCompany);
- virtual bool GetDescription(std::string* _rDescription);
+
+ virtual std::vector<std::string> GetNames();
+ virtual std::string GetCompany();
+ virtual std::vector<std::string> GetDescriptions();
private:
enum
@@ -60,23 +63,26 @@ class CBannerLoaderGC
char comment[128]; // Game description shown in IPL game start screen in two lines.
};
- // "opening.bnr" file format for JP/US console
+ // "opening.bnr" file format for EU console
struct DVDBanner
{
- u32 id; // 'BNR1'
+ u32 id; // 'BNR2'
u32 padding[7];
u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image
- DVDBannerComment comment;
+ DVDBannerComment comment[6]; // Comments in six languages (only 1 for BNR1 type)
};
- // "opening.bnr" file format for EU console
- struct DVDBanner2
+ 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])
{
- 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
- };
+ auto const string_decoder = CVolumeGC::GetStringDecoder(m_country);
+
+ // strnlen to trim NULLs
+ return string_decoder(std::string(data, strnlen(data, sizeof(data))));
+ }
u8* m_pBannerFile;
bool m_IsValid;
@@ -84,6 +90,8 @@ class CBannerLoaderGC
void decode5A3image(u32* dst, u16* src, int width, int height);
BANNER_TYPE getBannerType();
+
+ DiscIO::IVolume::ECountry const m_country;
};
} // namespace
diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
index b23dc4d91a..f606ed8876 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
@@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include <stdio.h>
+#include <algorithm>
#include "Common.h"
#include "ColorUtil.h"
@@ -144,73 +145,48 @@ bool CBannerLoaderWii::GetBanner(u32* _pBannerImage)
return true;
}
-bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& s)
-{
- bool ret = false;
-
- if (IsValid())
- {
- // find Banner type
- SWiiBanner *pBanner = (SWiiBanner*)m_pBannerFile;
-
- // Ensure the string is null-terminating, since the banner format
- // doesn't require it
- u16 *src = new u16[COMMENT_SIZE + 1];
- memcpy(src, &pBanner->m_Comment[index], COMMENT_SIZE * sizeof(u16));
- src[COMMENT_SIZE] = 0;
-
- ret = CopyBeUnicodeToString(s, src, COMMENT_SIZE + 1);
-
- delete [] src;
- }
-
- return ret;
-}
-
-bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::wstring& s)
+bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result)
{
if (IsValid())
{
- // find Banner type
- SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
-
- std::wstring description;
- for (int i = 0; i < COMMENT_SIZE; ++i)
- description.push_back(Common::swap16(pBanner->m_Comment[index][i]));
-
- s = description;
+ auto const banner = reinterpret_cast<const SWiiBanner*>(m_pBannerFile);
+ auto const src_ptr = banner->m_Comment[index];
+
+ // Trim at first NULL
+ 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;
}
-bool CBannerLoaderWii::GetName(std::string* _rName)
+std::vector<std::string> CBannerLoaderWii::GetNames()
{
- return GetStringFromComments(NAME_IDX, *_rName);
-}
+ std::vector<std::string> ret(1);
+
+ if (!GetStringFromComments(NAME_IDX, ret[0]))
+ ret.clear();
-bool CBannerLoaderWii::GetName(std::vector<std::wstring>& _rNames)
-{
- std::wstring temp;
- bool ret = GetStringFromComments(NAME_IDX, temp);
- _rNames.push_back(temp);
return ret;
}
-bool CBannerLoaderWii::GetCompany(std::string& _rCompany)
-{
- _rCompany = "N/A";
- return true;
-}
-
-bool CBannerLoaderWii::GetDescription(std::string* _rDescription)
+std::string CBannerLoaderWii::GetCompany()
{
- return GetStringFromComments(DESC_IDX, *_rDescription);
+ return "";
}
-bool CBannerLoaderWii::GetDescription(std::wstring& _rDescription)
+std::vector<std::string> CBannerLoaderWii::GetDescriptions()
{
- return GetStringFromComments(DESC_IDX, _rDescription);
+ std::vector<std::string> result(1);
+ if (!GetStringFromComments(DESC_IDX, result[0]))
+ result.clear();
+ return result;
}
void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height)
diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h
index 83733cf5ed..036eeeacbd 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderWii.h
+++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h
@@ -35,15 +35,9 @@ class CBannerLoaderWii
virtual bool GetBanner(u32* _pBannerImage);
- virtual bool GetName(std::string* _rName);
-
- bool GetName(std::vector<std::wstring>& _rNames);
-
- virtual bool GetCompany(std::string& _rCompany);
-
- virtual bool GetDescription(std::string* _rDescription);
-
- bool GetDescription(std::wstring& _rDescription);
+ virtual std::vector<std::string> GetNames();
+ virtual std::string GetCompany();
+ virtual std::vector<std::string> GetDescriptions();
private:
@@ -81,7 +75,6 @@ class CBannerLoaderWii
void decode5A3image(u32* dst, u16* src, int width, int height);
bool GetStringFromComments(const CommentIndex index, std::string& s);
- bool GetStringFromComments(const CommentIndex index, std::wstring& s);
};
} // namespace
diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp
index e69f8ff34c..2638f3fac4 100644
--- a/Source/Core/DiscIO/Src/DriveBlob.cpp
+++ b/Source/Core/DiscIO/Src/DriveBlob.cpp
@@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "DriveBlob.h"
+#include "StringUtil.h"
namespace DiscIO
{
@@ -23,12 +24,9 @@ namespace DiscIO
DriveReader::DriveReader(const char *drive)
{
#ifdef _WIN32
- char path[MAX_PATH];
- strncpy(path, drive, 3);
- path[2] = 0;
- sprintf(path, "\\\\.\\%s", drive);
SectorReader::SetSectorSize(2048);
- hDisc = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ auto const path = UTF8ToTStr(std::string("\\\\.\\") + drive);
+ hDisc = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
if (hDisc != INVALID_HANDLE_VALUE)
{
diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
index 47651e2f23..93b569e043 100644
--- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
@@ -20,6 +20,7 @@
#include <string>
#include <vector>
+#include <algorithm>
#include "FileSystemGCWii.h"
#include "StringUtil.h"
@@ -27,10 +28,10 @@
namespace DiscIO
{
CFileSystemGCWii::CFileSystemGCWii(const IVolume *_rVolume)
- : IFileSystem(_rVolume),
- m_Initialized(false),
- m_Valid(false),
- m_OffsetShift(0)
+ : IFileSystem(_rVolume)
+ , m_Initialized(false)
+ , m_Valid(false)
+ , m_OffsetShift(0)
{
m_Valid = DetectFileSystem();
}
@@ -213,9 +214,16 @@ u32 CFileSystemGCWii::Read32(u64 _Offset) const
return Common::swap32(Temp);
}
-void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const
+std::string CFileSystemGCWii::GetStringFromOffset(u64 _Offset) const
{
- m_rVolume->Read(_Offset, 255, (u8*)Filename);
+ std::string data;
+ data.resize(255);
+ m_rVolume->Read(_Offset, data.size(), (u8*)&data[0]);
+ data.erase(std::find(data.begin(), data.end(), 0x00), data.end());
+
+ // TODO: Should we really always use SHIFT-JIS?
+ // It makes some filenames in Pikmin (NTSC-U) sane, but is it correct?
+ return SHIFTJISToUTF8(data);
}
size_t CFileSystemGCWii::GetFileList(std::vector<const SFileInfo *> &_rFilenames)
@@ -311,18 +319,16 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _
{
SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex];
u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF);
- char filename[512];
- memset(filename, 0, sizeof(filename));
- GetStringFromOffset(uOffset, filename);
+ std::string filename = GetStringFromOffset(uOffset);
// check next index
if (rFileInfo->IsDirectory())
{
// this is a directory, build up the new szDirectory
if (_szDirectory != NULL)
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename);
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename.c_str());
else
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename);
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename.c_str());
CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset);
}
@@ -330,9 +336,9 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _
{
// this is a filename
if (_szDirectory != NULL)
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename);
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename.c_str());
else
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename);
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename.c_str());
CurrentIndex++;
}
diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.h b/Source/Core/DiscIO/Src/FileSystemGCWii.h
index 0e7d836d75..9054ade272 100644
--- a/Source/Core/DiscIO/Src/FileSystemGCWii.h
+++ b/Source/Core/DiscIO/Src/FileSystemGCWii.h
@@ -28,7 +28,7 @@ namespace DiscIO
class CFileSystemGCWii : public IFileSystem
{
public:
- CFileSystemGCWii(const IVolume *_rVolume);
+ CFileSystemGCWii(const IVolume* _rVolume);
virtual ~CFileSystemGCWii();
virtual bool IsValid() const { return m_Valid; }
virtual u64 GetFileSize(const char* _rFullPath);
@@ -44,11 +44,11 @@ public:
private:
bool m_Initialized;
bool m_Valid;
-
u32 m_OffsetShift; // WII offsets are all shifted
+
std::vector <SFileInfo> m_FileInfoVector;
u32 Read32(u64 _Offset) const;
- void GetStringFromOffset(u64 _Offset, char* Filename) const;
+ std::string GetStringFromOffset(u64 _Offset) const;
const SFileInfo* FindFileInfo(const char* _rFullPath);
bool DetectFileSystem();
void InitFileSystem();
diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h
index 557c71c31f..c19aaf93a8 100644
--- a/Source/Core/DiscIO/Src/Volume.h
+++ b/Source/Core/DiscIO/Src/Volume.h
@@ -22,6 +22,7 @@
#include <vector>
#include "Common.h"
+#include "StringUtil.h"
namespace DiscIO
{
@@ -37,8 +38,9 @@ public:
virtual void GetTMD(u8*, u32 *_sz) const { *_sz=0; }
virtual std::string GetUniqueID() const = 0;
virtual std::string GetMakerID() const = 0;
- virtual std::string GetName() const = 0;
- virtual bool GetWName(std::vector<std::wstring>& _rwNames) const { return false; }
+ // TODO: eliminate?
+ virtual std::string GetName() const;
+ virtual std::vector<std::string> GetNames() const = 0;
virtual u32 GetFSTSize() const = 0;
virtual std::string GetApploaderDate() const = 0;
virtual bool SupportsIntegrityCheck() const { return false; }
diff --git a/Source/Core/DiscIO/Src/VolumeCommon.cpp b/Source/Core/DiscIO/Src/VolumeCommon.cpp
index 415af2725a..4ab433680d 100644
--- a/Source/Core/DiscIO/Src/VolumeCommon.cpp
+++ b/Source/Core/DiscIO/Src/VolumeCommon.cpp
@@ -111,5 +111,13 @@ u8 GetSysMenuRegion(u16 _TitleVersion)
}
}
-};
+std::string IVolume::GetName() const
+{
+ auto names = GetNames();
+ if (names.empty())
+ return "";
+ else
+ return names[0];
+}
+}
diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
index dc76e2e641..be7cdeb565 100644
--- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
@@ -207,11 +207,10 @@ std::string CVolumeDirectory::GetMakerID() const
return "VOID";
}
-std::string CVolumeDirectory::GetName() const
+std::vector<std::string> CVolumeDirectory::GetNames() const
{
_dbg_assert_(DVDINTERFACE, m_diskHeader);
- std::string name = (char*)(m_diskHeader + 0x20);
- return name;
+ return std::vector<std::string>(1, (char*)(m_diskHeader + 0x20));
}
void CVolumeDirectory::SetName(std::string _Name)
diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h
index 0547be3b8a..880a6eebc1 100644
--- a/Source/Core/DiscIO/Src/VolumeDirectory.h
+++ b/Source/Core/DiscIO/Src/VolumeDirectory.h
@@ -50,7 +50,7 @@ public:
std::string GetMakerID() const;
- std::string GetName() const;
+ std::vector<std::string> GetNames() const;
void SetName(std::string);
u32 GetFSTSize() const;
diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp
index 09e2c5eaa9..6210172790 100644
--- a/Source/Core/DiscIO/Src/VolumeGC.cpp
+++ b/Source/Core/DiscIO/Src/VolumeGC.cpp
@@ -91,16 +91,17 @@ std::string CVolumeGC::GetMakerID() const
return makerID;
}
-std::string CVolumeGC::GetName() const
+std::vector<std::string> CVolumeGC::GetNames() const
{
- if (m_pReader == NULL)
- return "";
+ std::vector<std::string> names;
+
+ auto const string_decoder = GetStringDecoder(GetCountry());
- char name[128];
- if (!Read(0x20, 0x60, (u8*)&name))
- return "";
+ char name[0x60 + 1] = {};
+ if (m_pReader != NULL && Read(0x20, 0x60, (u8*)name))
+ names.push_back(string_decoder(name));
- return name;
+ return names;
}
u32 CVolumeGC::GetFSTSize() const
@@ -144,4 +145,10 @@ bool CVolumeGC::IsDiscTwo() const
return discTwo;
}
+auto CVolumeGC::GetStringDecoder(ECountry country) -> StringDecoder
+{
+ return (COUNTRY_JAPAN == country || COUNTRY_TAIWAN == country) ?
+ SHIFTJISToUTF8 : CP1252ToUTF8;
+}
+
} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h
index 4221df9493..d7729ee04c 100644
--- a/Source/Core/DiscIO/Src/VolumeGC.h
+++ b/Source/Core/DiscIO/Src/VolumeGC.h
@@ -34,12 +34,16 @@ public:
bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const;
std::string GetUniqueID() const;
std::string GetMakerID() const;
- std::string GetName() const;
+ std::vector<std::string> GetNames() const;
u32 GetFSTSize() const;
std::string GetApploaderDate() const;
ECountry GetCountry() const;
u64 GetSize() const;
bool IsDiscTwo() const;
+
+ typedef std::string(*StringDecoder)(const std::string&);
+
+ static StringDecoder GetStringDecoder(ECountry country);
private:
IBlobReader* m_pReader;
diff --git a/Source/Core/DiscIO/Src/VolumeWad.cpp b/Source/Core/DiscIO/Src/VolumeWad.cpp
index 2f9f0ef961..a10e5bdb42 100644
--- a/Source/Core/DiscIO/Src/VolumeWad.cpp
+++ b/Source/Core/DiscIO/Src/VolumeWad.cpp
@@ -15,6 +15,7 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
+#include <algorithm>
#include <math.h>
#include "VolumeWad.h"
@@ -107,78 +108,42 @@ bool CVolumeWAD::GetTitleID(u8* _pBuffer) const
return true;
}
-bool CVolumeWAD::GetWName(std::vector<std::wstring>& _rwNames) const
+std::vector<std::string> CVolumeWAD::GetNames() const
{
- u32 footer_size;
+ std::vector<std::string> names;
+ u32 footer_size;
if (!Read(0x1C, 4, (u8*)&footer_size))
{
- return false;
+ return names;
}
+
+ footer_size = Common::swap32(footer_size);
+
//Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean
-
- // Offset to the english title
- for (int i = 0; i < 10; i++)
+ for (int i = 0; i != 10; ++i)
{
- u16 temp[42];
- std::wstring out_temp;
+ static const u32 string_length = 42;
+ static const u32 bytes_length = string_length * sizeof(u16);
+
+ u16 temp[string_length];
- if (!Read(0x9C + (i*84) + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1
- || !temp[0])
+ if (footer_size < 0xF1 || !Read(0x9C + (i * bytes_length) + OpeningBnrOffset, bytes_length, (u8*)&temp))
{
- _rwNames.push_back(L"");
- continue;
+ names.push_back("");
}
- for (int j = 0; j < 42; ++j)
+ else
{
- u16 t = Common::swap16(temp[j]);
- if (t == 0 && j > 0)
- {
- if (out_temp.at(out_temp.size()-1) != ' ')
- out_temp.push_back(' ');
- }
- else
- out_temp.push_back(t);
- }
-
- _rwNames.push_back(out_temp);
- }
- return true;
-}
-
-std::string CVolumeWAD::GetName() const
-{
- u32 footer_size;
-
- if (!Read(0x1C, 4, (u8*)&footer_size))
- return "";
-
-
- //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean
-
- // Offset to the english title
- char temp[84];
- if (!Read(0xF1 + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 ||
- !Common::swap16(temp[0]))
- return "";
-
- // Remove the null bytes due to 16bit char length
- std::string out_temp;
- for (unsigned int i = 0; i < sizeof(temp); i+=2)
- {
- // Replace null chars with a single space per null section
- if (temp[i] == '\0' && i > 0)
- {
- if (out_temp.at(out_temp.size()-1) != ' ')
- out_temp.push_back(' ');
+ 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));
}
- else
- out_temp.push_back(temp[i]);
}
- // Make it a null terminated string
- out_temp.replace(out_temp.end()-1, out_temp.end(), 1, '\0');
- return out_temp;
+ return names;
}
u64 CVolumeWAD::GetSize() const
diff --git a/Source/Core/DiscIO/Src/VolumeWad.h b/Source/Core/DiscIO/Src/VolumeWad.h
index 956844acd1..afc16766a2 100644
--- a/Source/Core/DiscIO/Src/VolumeWad.h
+++ b/Source/Core/DiscIO/Src/VolumeWad.h
@@ -38,8 +38,7 @@ public:
bool GetTitleID(u8* _pBuffer) const;
std::string GetUniqueID() const;
std::string GetMakerID() const;
- std::string GetName() const;
- bool GetWName(std::vector<std::wstring>& _rwNames) const;
+ std::vector<std::string> GetNames() const;
u32 GetFSTSize() const { return 0; }
std::string GetApploaderDate() const { return "0"; }
ECountry GetCountry() const;
diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
index ca010b5ae4..32aa92bd08 100644
--- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
+++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
@@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "VolumeWiiCrypted.h"
+#include "VolumeGC.h"
#include "StringUtil.h"
#include "Crypto/sha1.h"
@@ -168,21 +169,17 @@ std::string CVolumeWiiCrypted::GetMakerID() const
return makerID;
}
-std::string CVolumeWiiCrypted::GetName() const
+std::vector<std::string> CVolumeWiiCrypted::GetNames() const
{
- if (m_pReader == NULL)
- {
- return std::string();
- }
-
- char name[0xFF];
+ std::vector<std::string> names;
+
+ auto const string_decoder = CVolumeGC::GetStringDecoder(GetCountry());
- if (!Read(0x20, 0x60, (u8*)&name))
- {
- return std::string();
- }
+ char name[0xFF] = {};
+ if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name))
+ names.push_back(string_decoder(name));
- return name;
+ return names;
}
u32 CVolumeWiiCrypted::GetFSTSize() const
diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h
index 5010e46bbd..56c2a8a363 100644
--- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h
+++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h
@@ -37,7 +37,7 @@ public:
void GetTMD(u8* _pBuffer, u32* _sz) const;
std::string GetUniqueID() const;
std::string GetMakerID() const;
- std::string GetName() const;
+ std::vector<std::string> GetNames() const;
u32 GetFSTSize() const;
std::string GetApploaderDate() const;
ECountry GetCountry() const;