summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2013-03-27 13:19:23 +1100
committerskidau <skidau@gmail.com>2013-03-27 13:19:23 +1100
commit7784fa4c67cc8d2545f45694d83805e7e89cd583 (patch)
tree7724133aabe971ec417d1dea0977a525bb8debfb /Source/Core/DiscIO
parentd33c19b0cd2bae982c8d35e86a9d3551f9e5c72f (diff)
parent5cea0d9defeaa23e7af94adf7615a44fb2c9c173 (diff)
Merge branch 'master' into wii-network
# By Ryan Houdek (185) and others # Via degasus (12) and others * master: (625 commits) Revert "Don't open/close file for every file operation." as it was crashing PokePark in Windows builds. Array overrun fixed in VertexShaderCache for the DX11 plugin. Fixed DSPTool build. Windows build fix Go back to assuming every HID device is a wiimote on Windows. Fixed issue 6117. Unfixed issue 6031. VideoSoftware: Improve fog range adjustment by using less magic and more comments. revert RasterFont for VideoSoftware ogl: fix virtual xfb Windows build fix from web interface... Adjusted the audio loop criteria, using >= on the Wii and == on GC. This fixes the audio static that occurred in Wii games after hours of play. Forced the exception check only for ARAM DMA transfers. Removed the Eternal Darkness boot hack and replaced it with an exception check. VideoSoftware: Implement fog range adjustment, fixing issue 6147. implement 4xSSAA for OGL move ogl-only settings into backend Fix description of disable fog, and move it to enhancements tab. Reverted rd76ca5783743 as it was made obsolete by r1d550f4496e4. Removed the tracking of the FIFO Writes as it was made obsolete by r1d550f4496e4. Forced the external exception check to occur sooner by changing the downcount. Mark the Direct3D9 backend deprecated. Prefer D3D11 and OpenGL over D3D9 by default. ... Conflicts: CMakeLists.txt Source/Core/Common/Common.vcxproj.filters Source/Core/Common/Src/CommonPaths.h Source/Core/Core/Core.vcxproj.filters Source/Core/Core/Src/Core.cpp Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp Source/VSProps/Dolphin.Win32.props Source/VSProps/Dolphin.x64.props
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj4
-rw-r--r--Source/Core/DiscIO/Src/BannerLoader.cpp176
-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/CISOBlob.cpp64
-rw-r--r--Source/Core/DiscIO/Src/CISOBlob.h44
-rw-r--r--Source/Core/DiscIO/Src/CompressedBlob.cpp3
-rw-r--r--Source/Core/DiscIO/Src/DriveBlob.cpp8
-rw-r--r--Source/Core/DiscIO/Src/FileHandlerARC.cpp24
-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/NANDContentLoader.cpp2
-rw-r--r--Source/Core/DiscIO/Src/NANDContentLoader.h64
-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.h4
-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
-rw-r--r--Source/Core/DiscIO/Src/WbfsBlob.cpp28
-rw-r--r--Source/Core/DiscIO/Src/WbfsBlob.h2
-rw-r--r--Source/Core/DiscIO/Src/WiiWad.cpp121
-rw-r--r--Source/Core/DiscIO/Src/WiiWad.h4
30 files changed, 409 insertions, 624 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 6451c73670..d38c7e9ea4 100644
--- a/Source/Core/DiscIO/Src/BannerLoader.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoader.cpp
@@ -22,180 +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>
-#include <iconv.h>
-#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
- 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
- return returnCode;
-}
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume)
{
@@ -203,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/CISOBlob.cpp b/Source/Core/DiscIO/Src/CISOBlob.cpp
index b3a2e31b2b..8d267c15fb 100644
--- a/Source/Core/DiscIO/Src/CISOBlob.cpp
+++ b/Source/Core/DiscIO/Src/CISOBlob.cpp
@@ -15,24 +15,30 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
+#include <algorithm>
+#include <cmath>
+
#include "Blob.h"
#include "CISOBlob.h"
namespace DiscIO
{
+static const char CISO_MAGIC[] = "CISO";
+
CISOFileReader::CISOFileReader(std::FILE* file)
: m_file(file)
{
m_size = m_file.GetSize();
-
- memset(&header, 0, sizeof(header));
+
+ CISOHeader header;
m_file.ReadArray(&header, 1);
+
+ m_block_size = header.block_size;
- CISO_Map_t count = 0;
- int idx;
- for (idx = 0; idx < CISO_MAP_SIZE; idx++)
- ciso_map[idx] = (header.map[idx] == 1) ? count++ : CISO_UNUSED_BLOCK;
+ MapType count = 0;
+ for (u32 idx = 0; idx < CISO_MAP_SIZE; idx++)
+ m_ciso_map[idx] = (1 == header.map[idx]) ? count++ : UNUSED_BLOCK_ID;
}
CISOFileReader* CISOFileReader::Create(const char* filename)
@@ -46,34 +52,45 @@ CISOFileReader* CISOFileReader::Create(const char* filename)
return NULL;
}
+u64 CISOFileReader::GetDataSize() const
+{
+ return GetRawSize();
+}
+
+u64 CISOFileReader::GetRawSize() const
+{
+ return m_size;
+}
+
bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
{
- u64 bytesRead = 0;
- while (bytesRead < nbytes)
+ while (nbytes != 0)
{
- u32 block = (u32)(offset / header.block_size);
- u32 data_offset = offset % header.block_size;
- u32 bytes_to_read = (u32)min((u64)(header.block_size - data_offset), nbytes);
- if ((block >= CISO_MAP_SIZE) || (ciso_map[block] == CISO_UNUSED_BLOCK))
+ auto const block = offset / m_block_size;
+ auto const data_offset = offset % m_block_size;
+
+ auto const bytes_to_read = std::min(m_block_size - data_offset, nbytes);
+ if (block < CISO_MAP_SIZE && UNUSED_BLOCK_ID != m_ciso_map[block])
{
- memset(out_ptr, 0, bytes_to_read);
+ // calcualte the base address
+ auto const file_off = CISO_HEADER_SIZE + m_ciso_map[block] * m_block_size + data_offset;
+
+ if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadArray(out_ptr, bytes_to_read)))
+ return false;
+
out_ptr += bytes_to_read;
offset += bytes_to_read;
- bytesRead += bytes_to_read;
+ nbytes -= bytes_to_read;
}
else
{
- // calcualte the base address
- u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset;
-
- if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadBytes(out_ptr, bytes_to_read)))
- return false;
-
+ std::fill_n(out_ptr, bytes_to_read, 0);
out_ptr += bytes_to_read;
offset += bytes_to_read;
- bytesRead += bytes_to_read;
+ nbytes -= bytes_to_read;
}
}
+
return true;
}
@@ -81,8 +98,9 @@ bool IsCISOBlob(const char* filename)
{
File::IOFile f(filename, "rb");
- CISO_Head_t header;
- return (f.ReadArray(&header, 1) && (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0));
+ CISOHeader header;
+ return (f.ReadArray(&header, 1) &&
+ std::equal(header.magic, header.magic + sizeof(header.magic), CISO_MAGIC));
}
} // namespace
diff --git a/Source/Core/DiscIO/Src/CISOBlob.h b/Source/Core/DiscIO/Src/CISOBlob.h
index e87e616a21..9b490f0638 100644
--- a/Source/Core/DiscIO/Src/CISOBlob.h
+++ b/Source/Core/DiscIO/Src/CISOBlob.h
@@ -21,43 +21,45 @@
#include "Blob.h"
#include "FileUtil.h"
-#define CISO_MAGIC "CISO"
-#define CISO_HEAD_SIZE (0x8000)
-#define CISO_MAP_SIZE (CISO_HEAD_SIZE - 8)
-
namespace DiscIO
{
bool IsCISOBlob(const char* filename);
-// Blocks that won't compress to less than 97% of the original size are stored as-is.
-struct CISO_Head_t
+static const u32 CISO_HEADER_SIZE = 0x8000;
+static const u32 CISO_MAP_SIZE = CISO_HEADER_SIZE - sizeof(u32) - sizeof(char) * 4;
+
+struct CISOHeader
{
- u8 magic[4]; // "CISO"
- u32 block_size; // stored as litte endian (not network byte order)
- u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid
+ // "CISO"
+ char magic[4];
+
+ // little endian
+ u32 block_size;
+
+ // 0=unused, 1=used, others=invalid
+ u8 map[CISO_MAP_SIZE];
};
-typedef u16 CISO_Map_t;
-
-const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0;
-
class CISOFileReader : public IBlobReader
{
- File::IOFile m_file;
- CISOFileReader(std::FILE* file);
- s64 m_size;
-
public:
static CISOFileReader* Create(const char* filename);
- u64 GetDataSize() const { return m_size; }
- u64 GetRawSize() const { return m_size; }
+ u64 GetDataSize() const;
+ u64 GetRawSize() const;
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
private:
- CISO_Head_t header;
- CISO_Map_t ciso_map[CISO_MAP_SIZE];
+ CISOFileReader(std::FILE* file);
+
+ typedef u16 MapType;
+ static const MapType UNUSED_BLOCK_ID = -1;
+
+ File::IOFile m_file;
+ u64 m_size;
+ u32 m_block_size;
+ MapType m_ciso_map[CISO_MAP_SIZE];
};
} // namespace
diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp
index c4b1aa1385..2bc4a93ede 100644
--- a/Source/Core/DiscIO/Src/CompressedBlob.cpp
+++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp
@@ -301,7 +301,10 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca
File::IOFile f(outfile, "wb");
if (!f)
+ {
+ delete reader;
return false;
+ }
const CompressedBlobHeader &header = reader->GetHeader();
u8* buffer = new u8[header.block_size];
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/FileHandlerARC.cpp b/Source/Core/DiscIO/Src/FileHandlerARC.cpp
index a9e4beee5d..63a4876718 100644
--- a/Source/Core/DiscIO/Src/FileHandlerARC.cpp
+++ b/Source/Core/DiscIO/Src/FileHandlerARC.cpp
@@ -27,19 +27,19 @@
namespace DiscIO
{
CARCFile::CARCFile(const std::string& _rFilename)
- : m_pBuffer(NULL)
- , m_Initialized(false)
+ : m_pBuffer(NULL)
+ , m_Initialized(false)
{
- DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str());
- if (pReader != NULL)
- {
- u64 FileSize = pReader->GetDataSize();
- m_pBuffer = new u8[(u32)FileSize];
- pReader->Read(0, FileSize, m_pBuffer);
- delete pReader;
-
- m_Initialized = ParseBuffer();
- }
+ DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str());
+ if (pReader != NULL)
+ {
+ u64 FileSize = pReader->GetDataSize();
+ m_pBuffer = new u8[(u32)FileSize];
+ pReader->Read(0, FileSize, m_pBuffer);
+ delete pReader;
+
+ m_Initialized = ParseBuffer();
+ }
}
CARCFile::CARCFile(const std::string& _rFilename, u32 offset)
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/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp
index 3c00d66be5..110efd6fa9 100644
--- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp
+++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp
@@ -273,7 +273,7 @@ bool CNANDContentLoader::Initialize(const std::string& _rName)
continue;
}
- rContent.m_pData = NULL;
+ rContent.m_pData = NULL;
char szFilename[1024];
if (rContent.m_Type & 0x8000) // shared app
diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h
index 63135df693..f95ae6586c 100644
--- a/Source/Core/DiscIO/Src/NANDContentLoader.h
+++ b/Source/Core/DiscIO/Src/NANDContentLoader.h
@@ -32,14 +32,14 @@ namespace DiscIO
bool Add_Ticket(u64 TitleID, const u8 *p_tik, u32 tikSize);
struct SNANDContent
{
- u32 m_ContentID;
- u16 m_Index;
- u16 m_Type;
- u32 m_Size;
- u8 m_SHA1Hash[20];
- u8 m_Header[36]; //all of the above
-
- u8* m_pData;
+ u32 m_ContentID;
+ u16 m_Index;
+ u16 m_Type;
+ u32 m_Size;
+ u8 m_SHA1Hash[20];
+ u8 m_Header[36]; //all of the above
+
+ u8* m_pData;
};
// pure virtual interface so just the NANDContentManager can create these files only
@@ -47,34 +47,34 @@ class INANDContentLoader
{
public:
- INANDContentLoader() {}
+ INANDContentLoader() {}
- virtual ~INANDContentLoader() {}
+ virtual ~INANDContentLoader() {}
- virtual bool IsValid() const = 0;
+ virtual bool IsValid() const = 0;
virtual void RemoveTitle() const = 0;
- virtual u64 GetTitleID() const = 0;
- virtual u16 GetIosVersion() const = 0;
- virtual u32 GetBootIndex() const = 0;
- virtual size_t GetContentSize() const = 0;
- virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
+ virtual u64 GetTitleID() const = 0;
+ virtual u16 GetIosVersion() const = 0;
+ virtual u32 GetBootIndex() const = 0;
+ virtual size_t GetContentSize() const = 0;
+ virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
virtual const u8* GetTMDView() const = 0;
virtual const u8* GetTMDHeader() const = 0;
virtual u32 GetTIKSize() const = 0;
virtual const u8* GetTIK() const = 0;
- virtual const std::vector<SNANDContent>& GetContent() const = 0;
- virtual u16 GetTitleVersion() const = 0;
- virtual u16 GetNumEntries() const = 0;
- virtual DiscIO::IVolume::ECountry GetCountry() const = 0;
+ virtual const std::vector<SNANDContent>& GetContent() const = 0;
+ virtual u16 GetTitleVersion() const = 0;
+ virtual u16 GetNumEntries() const = 0;
+ virtual DiscIO::IVolume::ECountry GetCountry() const = 0;
virtual u8 GetCountryChar() const = 0;
- enum
- {
- TMD_VIEW_SIZE = 0x58,
- TMD_HEADER_SIZE = 0x1e4,
+ enum
+ {
+ TMD_VIEW_SIZE = 0x58,
+ TMD_HEADER_SIZE = 0x1e4,
CONTENT_HEADER_SIZE = 0x24,
TICKET_SIZE = 0x2A4
- };
+ };
};
@@ -83,22 +83,22 @@ class CNANDContentManager
{
public:
- static CNANDContentManager& Access() { return m_Instance; }
+ static CNANDContentManager& Access() { return m_Instance; }
u64 Install_WiiWAD(std::string &fileName);
- const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false);
+ const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false);
const INANDContentLoader& GetNANDLoader(u64 _titleId, bool forceReload = false);
bool RemoveTitle(u64 _titleID);
private:
- CNANDContentManager() {};
+ CNANDContentManager() {};
- ~CNANDContentManager();
+ ~CNANDContentManager();
- static CNANDContentManager m_Instance;
+ static CNANDContentManager m_Instance;
- typedef std::map<std::string, INANDContentLoader*> CNANDContentMap;
- CNANDContentMap m_Map;
+ typedef std::map<std::string, INANDContentLoader*> CNANDContentMap;
+ CNANDContentMap m_Map;
};
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..4e28d6460f 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;
@@ -59,7 +59,7 @@ public:
ECountry GetCountry() const;
- u64 GetSize() const;
+ u64 GetSize() const;
void BuildFST();
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;
diff --git a/Source/Core/DiscIO/Src/WbfsBlob.cpp b/Source/Core/DiscIO/Src/WbfsBlob.cpp
index 1b7696cc58..0fd89243e3 100644
--- a/Source/Core/DiscIO/Src/WbfsBlob.cpp
+++ b/Source/Core/DiscIO/Src/WbfsBlob.cpp
@@ -75,47 +75,47 @@ bool WbfsFileReader::OpenFiles(const char* filename)
delete new_entry;
return 0 != m_total_files;
}
-
+
new_entry->base_address = m_size;
new_entry->size = new_entry->file.GetSize();
m_size += new_entry->size;
m_total_files ++;
- m_files.push_back(new_entry);
+ m_files.push_back(new_entry);
}
}
bool WbfsFileReader::ReadHeader()
{
m_files[0]->file.Seek(4, SEEK_SET);
-
+
// Read hd size info
m_files[0]->file.ReadBytes(&hd_sector_count, 4);
hd_sector_count = Common::swap32(hd_sector_count);
-
+
m_files[0]->file.ReadBytes(&hd_sector_shift, 1);
hd_sector_size = 1 << hd_sector_shift;
-
+
if(m_size != hd_sector_count * hd_sector_size)
{
//printf("File size doesn't match expected size\n");
return false;
}
-
+
// Read wbfs cluster info
m_files[0]->file.ReadBytes(&wbfs_sector_shift, 1);
wbfs_sector_size = 1 << wbfs_sector_shift;
wbfs_sector_count = m_size / wbfs_sector_size;
-
+
if(wbfs_sector_size < wii_sector_size)
{
//Setting this too low would case a very large memory allocation
return false;
}
-
+
m_blocks_per_disc = (wii_sector_count * wii_sector_size) / wbfs_sector_size;
m_disc_info_size = align(wii_disc_header_size + m_blocks_per_disc * 2, hd_sector_size);
-
+
// Read disc table
m_files[0]->file.Seek(2, SEEK_CUR);
m_files[0]->file.ReadBytes(disc_table, 500);
@@ -125,7 +125,7 @@ bool WbfsFileReader::ReadHeader()
//printf("Game must be in 'slot 0'\n");
return false;
}
-
+
return true;
}
@@ -143,7 +143,7 @@ bool WbfsFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
nbytes -= read_size;
offset += read_size;
}
-
+
return true;
}
@@ -172,16 +172,16 @@ File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available)
}
}
}
-
+
PanicAlert("Read beyond end of disc");
m_files[0]->file.Seek(0, SEEK_SET);
return m_files[0]->file;
}
WbfsFileReader* WbfsFileReader::Create(const char* filename)
-{
+{
WbfsFileReader* reader = new WbfsFileReader(filename);
-
+
if(reader->IsGood())
{
return reader;
diff --git a/Source/Core/DiscIO/Src/WbfsBlob.h b/Source/Core/DiscIO/Src/WbfsBlob.h
index 300f658ddc..acae008fc2 100644
--- a/Source/Core/DiscIO/Src/WbfsBlob.h
+++ b/Source/Core/DiscIO/Src/WbfsBlob.h
@@ -63,7 +63,7 @@ class WbfsFileReader : public IBlobReader
u16* m_wlba_table;
u64 m_blocks_per_disc;
-
+
bool m_good;
public:
diff --git a/Source/Core/DiscIO/Src/WiiWad.cpp b/Source/Core/DiscIO/Src/WiiWad.cpp
index 24e091f9f4..d718436905 100644
--- a/Source/Core/DiscIO/Src/WiiWad.cpp
+++ b/Source/Core/DiscIO/Src/WiiWad.cpp
@@ -45,10 +45,11 @@ private:
WiiWAD::WiiWAD(const std::string& _rName)
{
- DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
- if (pReader == NULL || File::IsDirectory(_rName))
+ DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
+ if (pReader == NULL || File::IsDirectory(_rName))
{
m_Valid = false;
+ if(pReader) delete pReader;
return;
}
@@ -70,87 +71,87 @@ WiiWAD::~WiiWAD()
u8* WiiWAD::CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset)
{
- if (_Size > 0)
- {
- u8* pTmpBuffer = new u8[_Size];
- _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
+ if (_Size > 0)
+ {
+ u8* pTmpBuffer = new u8[_Size];
+ _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
- if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
- {
+ if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
+ {
ERROR_LOG(DISCIO, "WiiWAD: Could not read from file");
- PanicAlertT("WiiWAD: Could not read from file");
- }
- return pTmpBuffer;
- }
+ PanicAlertT("WiiWAD: Could not read from file");
+ }
+ return pTmpBuffer;
+ }
return NULL;
}
bool WiiWAD::ParseWAD(DiscIO::IBlobReader& _rReader)
{
- CBlobBigEndianReader ReaderBig(_rReader);
+ CBlobBigEndianReader ReaderBig(_rReader);
- // get header size
+ // get header size
u32 HeaderSize = ReaderBig.Read32(0);
- if (HeaderSize != 0x20)
- {
- _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20");
- return false;
- }
-
- // get header
- u8 Header[0x20];
- _rReader.Read(0, HeaderSize, Header);
+ if (HeaderSize != 0x20)
+ {
+ _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20");
+ return false;
+ }
+
+ // get header
+ u8 Header[0x20];
+ _rReader.Read(0, HeaderSize, Header);
u32 HeaderType = ReaderBig.Read32(0x4);
- if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType))
- return false;
-
- m_CertificateChainSize = ReaderBig.Read32(0x8);
- u32 Reserved = ReaderBig.Read32(0xC);
- m_TicketSize = ReaderBig.Read32(0x10);
- m_TMDSize = ReaderBig.Read32(0x14);
- m_DataAppSize = ReaderBig.Read32(0x18);
- m_FooterSize = ReaderBig.Read32(0x1C);
+ if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType))
+ return false;
+
+ m_CertificateChainSize = ReaderBig.Read32(0x8);
+ u32 Reserved = ReaderBig.Read32(0xC);
+ m_TicketSize = ReaderBig.Read32(0x10);
+ m_TMDSize = ReaderBig.Read32(0x14);
+ m_DataAppSize = ReaderBig.Read32(0x18);
+ m_FooterSize = ReaderBig.Read32(0x1C);
#if MAX_LOGLEVEL >= DEBUG_LEVEL
_dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00");
#else
(void)Reserved;
#endif
- u32 Offset = 0x40;
- m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40);
- m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40);
- m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40);
- m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40);
- m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40);
+ u32 Offset = 0x40;
+ m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40);
+ m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40);
+ m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40);
+ m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40);
+ m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40);
return true;
}
bool WiiWAD::IsWiiWAD(const std::string& _rName)
{
- DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
- if (pReader == NULL)
- return false;
-
- CBlobBigEndianReader Reader(*pReader);
- bool Result = false;
-
- // check for wii wad
- if (Reader.Read32(0x00) == 0x20)
- {
- u32 WADTYpe = Reader.Read32(0x04);
- switch(WADTYpe)
- {
- case 0x49730000:
- case 0x69620000:
- Result = true;
- }
- }
-
- delete pReader;
-
- return Result;
+ DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str());
+ if (pReader == NULL)
+ return false;
+
+ CBlobBigEndianReader Reader(*pReader);
+ bool Result = false;
+
+ // check for wii wad
+ if (Reader.Read32(0x00) == 0x20)
+ {
+ u32 WADTYpe = Reader.Read32(0x04);
+ switch(WADTYpe)
+ {
+ case 0x49730000:
+ case 0x69620000:
+ Result = true;
+ }
+ }
+
+ delete pReader;
+
+ return Result;
}
diff --git a/Source/Core/DiscIO/Src/WiiWad.h b/Source/Core/DiscIO/Src/WiiWad.h
index 3c219b6627..3b0bad1ed9 100644
--- a/Source/Core/DiscIO/Src/WiiWad.h
+++ b/Source/Core/DiscIO/Src/WiiWad.h
@@ -33,7 +33,7 @@ class WiiWAD
{
public:
- WiiWAD(const std::string& _rName);
+ WiiWAD(const std::string& _rName);
~WiiWAD();
@@ -50,7 +50,7 @@ public:
u8* GetDataApp() const { return m_pDataApp; }
u8* GetFooter() const { return m_pFooter; }
- static bool IsWiiWAD(const std::string& _rName);
+ static bool IsWiiWAD(const std::string& _rName);
private: