summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorbushing <bushing@gmail.com>2008-12-08 05:30:24 +0000
committerbushing <bushing@gmail.com>2008-12-08 05:30:24 +0000
commit49cfded60bb5b444d1828190eacc52bbb49a9cb8 (patch)
tree0823218c1f2f6eec307dadbdec18c5632625f052 /Source/Core/DiscIO
parent901fe7c00fec5e2aaf55d184edbcb6d092345d52 (diff)
set svn:eol-style=native for **.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1442 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/Src/BannerLoader.cpp206
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderGC.cpp386
-rw-r--r--Source/Core/DiscIO/Src/BannerLoaderWii.cpp448
-rw-r--r--Source/Core/DiscIO/Src/Blob.cpp220
-rw-r--r--Source/Core/DiscIO/Src/CompressedBlob.cpp684
-rw-r--r--Source/Core/DiscIO/Src/DriveBlob.cpp50
-rw-r--r--Source/Core/DiscIO/Src/FileBlob.cpp220
-rw-r--r--Source/Core/DiscIO/Src/FileHandlerARC.cpp474
-rw-r--r--Source/Core/DiscIO/Src/FileSystemGCWii.cpp498
-rw-r--r--Source/Core/DiscIO/Src/Filesystem.cpp100
-rw-r--r--Source/Core/DiscIO/Src/VolumeCreator.cpp524
-rw-r--r--Source/Core/DiscIO/Src/VolumeDirectory.cpp932
-rw-r--r--Source/Core/DiscIO/Src/VolumeGC.cpp338
-rw-r--r--Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp508
-rw-r--r--Source/Core/DiscIO/Src/stdafx.cpp42
15 files changed, 2815 insertions, 2815 deletions
diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp
index a0ec090973..60cee599b0 100644
--- a/Source/Core/DiscIO/Src/BannerLoader.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoader.cpp
@@ -1,103 +1,103 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-#include "stdafx.h"
-
-#include "BannerLoader.h"
-#include "BannerLoaderWii.h"
-#include "BannerLoaderGC.h"
-
-#include "VolumeCreator.h"
-#include "FileUtil.h"
-
-namespace DiscIO
-{
-bool IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src)
-{
- static bool bValidChars[256];
- static bool bInitialized = false;
-
- if (!bInitialized)
- {
- for (int i = 0; i < 256; i++)
- {
- bValidChars[i] = false;
- }
-
- // generate valid chars
- for (unsigned char c = 0x20; c <= 0x80; c++)
- {
- bValidChars[c] = true;
- }
-
- bValidChars[0x0a] = true;
- bValidChars[0xa9] = true;
- bValidChars[0xe9] = true;
-
- bInitialized = true;
- }
-
- bool bResult = true;
- char destBuffer[2048];
- 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)
- {
- bResult = false;
- break;
- }
-
- *dest = c;
- dest++;
- src++;
- }
-
- // finalize the string
- if (bResult)
- {
- *dest = 0x00;
- }
- else
- {
- dest[0] = ' ';
- dest[1] = 0x00;
- }
-
- _rDestination = destBuffer;
-
- return(bResult);
-}
-
-
-IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem)
-{
- if (IsVolumeWiiDisc(_rFileSystem.GetVolume()))
- {
- return(new CBannerLoaderWii(_rFileSystem));
- }
-
- return(new CBannerLoaderGC(_rFileSystem));
-}
-} // namespace
-
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+#include "stdafx.h"
+
+#include "BannerLoader.h"
+#include "BannerLoaderWii.h"
+#include "BannerLoaderGC.h"
+
+#include "VolumeCreator.h"
+#include "FileUtil.h"
+
+namespace DiscIO
+{
+bool IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src)
+{
+ static bool bValidChars[256];
+ static bool bInitialized = false;
+
+ if (!bInitialized)
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ bValidChars[i] = false;
+ }
+
+ // generate valid chars
+ for (unsigned char c = 0x20; c <= 0x80; c++)
+ {
+ bValidChars[c] = true;
+ }
+
+ bValidChars[0x0a] = true;
+ bValidChars[0xa9] = true;
+ bValidChars[0xe9] = true;
+
+ bInitialized = true;
+ }
+
+ bool bResult = true;
+ char destBuffer[2048];
+ 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)
+ {
+ bResult = false;
+ break;
+ }
+
+ *dest = c;
+ dest++;
+ src++;
+ }
+
+ // finalize the string
+ if (bResult)
+ {
+ *dest = 0x00;
+ }
+ else
+ {
+ dest[0] = ' ';
+ dest[1] = 0x00;
+ }
+
+ _rDestination = destBuffer;
+
+ return(bResult);
+}
+
+
+IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem)
+{
+ if (IsVolumeWiiDisc(_rFileSystem.GetVolume()))
+ {
+ return(new CBannerLoaderWii(_rFileSystem));
+ }
+
+ return(new CBannerLoaderGC(_rFileSystem));
+}
+} // namespace
+
diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
index 9e897c22d8..2480739979 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp
@@ -1,193 +1,193 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include "BannerLoaderGC.h"
-
-namespace DiscIO
-{
-CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem)
- : m_pBannerFile(NULL),
- m_IsValid(false)
-{
- // build LUT Table
- for (int i = 0; i < 8; i++)
- {
- lut3to8[i] = (i * 255) / 7;
- }
-
- for (int i = 0; i < 16; i++)
- {
- lut4to8[i] = (i * 255) / 15;
- }
-
- for (int i = 0; i < 32; i++)
- {
- lut5to8[i] = (i * 255) / 31;
- }
-
- // load the opening.bnr
- size_t FileSize = _rFileSystem.GetFileSize("opening.bnr");
-
- if (FileSize > 0)
- {
- m_pBannerFile = new u8[FileSize];
- _rFileSystem.ReadFile("opening.bnr", m_pBannerFile, FileSize);
- m_IsValid = true;
- }
-}
-
-
-CBannerLoaderGC::~CBannerLoaderGC()
-{
- delete [] m_pBannerFile;
- m_pBannerFile = NULL;
-}
-
-
-bool
-CBannerLoaderGC::IsValid()
-{
- return(m_IsValid);
-}
-
-
-bool
-CBannerLoaderGC::GetBanner(u32* _pBannerImage)
-{
- if (!IsValid())
- {
- return(false);
- }
-
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
- decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
-
- return(true);
-}
-
-
-bool
-CBannerLoaderGC::GetName(std::string& _rName, int language)
-{
- _rName = "invalid image";
-
- if (!IsValid())
- {
- return(false);
- }
-
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
-
- if (!CopyToStringAndCheck(_rName, language != 0 ? pBanner->comment[0].shortTitle : pBanner->comment[0].longTitle))
- {
- return(false);
- }
-
- return(true);
-}
-
-
-bool
-CBannerLoaderGC::GetCompany(std::string& _rCompany)
-{
- _rCompany = "invalid images";
-
- if (!IsValid())
- {
- return(false);
- }
-
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
-
- if (!CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker))
- {
- return(false);
- }
-
- return(true);
-}
-
-
-bool
-CBannerLoaderGC::GetDescription(std::string& _rDescription)
-{
- _rDescription = "invalid images";
-
- if (!IsValid())
- {
- return(false);
- }
-
- DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
-
- if (!CopyToStringAndCheck(_rDescription, pBanner->comment[0].comment))
- {
- _rDescription = "";
- }
-
- return(true);
-}
-
-
-u32
-CBannerLoaderGC::decode5A3(u16 val)
-{
- u32 bannerBGColor = 0x00000000;
-
- int r, g, b, a;
-
- if ((val & 0x8000))
- {
- r = lut5to8[(val >> 10) & 0x1f];
- g = lut5to8[(val >> 5) & 0x1f];
- b = lut5to8[(val) & 0x1f];
- a = 0xFF;
- }
- else
- {
- a = lut3to8[(val >> 12) & 0x7];
- r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
- g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
- b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
- a = 0xFF;
- }
-
- return((a << 24) | (r << 16) | (g << 8) | b);
-}
-
-
-void
-CBannerLoaderGC::decode5A3image(u32* dst, u16* src, int width, int height)
-{
- for (int y = 0; y < height; y += 4)
- {
- for (int x = 0; x < width; x += 4)
- {
- for (int iy = 0; iy < 4; iy++, src += 4)
- {
- for (int ix = 0; ix < 4; ix++)
- {
- u32 RGBA = decode5A3(Common::swap16(src[ix]));
- dst[(y + iy) * width + (x + ix)] = RGBA;
- }
- }
- }
- }
-}
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include "BannerLoaderGC.h"
+
+namespace DiscIO
+{
+CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem)
+ : m_pBannerFile(NULL),
+ m_IsValid(false)
+{
+ // build LUT Table
+ for (int i = 0; i < 8; i++)
+ {
+ lut3to8[i] = (i * 255) / 7;
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ lut4to8[i] = (i * 255) / 15;
+ }
+
+ for (int i = 0; i < 32; i++)
+ {
+ lut5to8[i] = (i * 255) / 31;
+ }
+
+ // load the opening.bnr
+ size_t FileSize = _rFileSystem.GetFileSize("opening.bnr");
+
+ if (FileSize > 0)
+ {
+ m_pBannerFile = new u8[FileSize];
+ _rFileSystem.ReadFile("opening.bnr", m_pBannerFile, FileSize);
+ m_IsValid = true;
+ }
+}
+
+
+CBannerLoaderGC::~CBannerLoaderGC()
+{
+ delete [] m_pBannerFile;
+ m_pBannerFile = NULL;
+}
+
+
+bool
+CBannerLoaderGC::IsValid()
+{
+ return(m_IsValid);
+}
+
+
+bool
+CBannerLoaderGC::GetBanner(u32* _pBannerImage)
+{
+ if (!IsValid())
+ {
+ return(false);
+ }
+
+ DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+ decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
+
+ return(true);
+}
+
+
+bool
+CBannerLoaderGC::GetName(std::string& _rName, int language)
+{
+ _rName = "invalid image";
+
+ if (!IsValid())
+ {
+ return(false);
+ }
+
+ DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+
+ if (!CopyToStringAndCheck(_rName, language != 0 ? pBanner->comment[0].shortTitle : pBanner->comment[0].longTitle))
+ {
+ return(false);
+ }
+
+ return(true);
+}
+
+
+bool
+CBannerLoaderGC::GetCompany(std::string& _rCompany)
+{
+ _rCompany = "invalid images";
+
+ if (!IsValid())
+ {
+ return(false);
+ }
+
+ DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+
+ if (!CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker))
+ {
+ return(false);
+ }
+
+ return(true);
+}
+
+
+bool
+CBannerLoaderGC::GetDescription(std::string& _rDescription)
+{
+ _rDescription = "invalid images";
+
+ if (!IsValid())
+ {
+ return(false);
+ }
+
+ DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
+
+ if (!CopyToStringAndCheck(_rDescription, pBanner->comment[0].comment))
+ {
+ _rDescription = "";
+ }
+
+ return(true);
+}
+
+
+u32
+CBannerLoaderGC::decode5A3(u16 val)
+{
+ u32 bannerBGColor = 0x00000000;
+
+ int r, g, b, a;
+
+ if ((val & 0x8000))
+ {
+ r = lut5to8[(val >> 10) & 0x1f];
+ g = lut5to8[(val >> 5) & 0x1f];
+ b = lut5to8[(val) & 0x1f];
+ a = 0xFF;
+ }
+ else
+ {
+ a = lut3to8[(val >> 12) & 0x7];
+ r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
+ g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
+ b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
+ a = 0xFF;
+ }
+
+ return((a << 24) | (r << 16) | (g << 8) | b);
+}
+
+
+void
+CBannerLoaderGC::decode5A3image(u32* dst, u16* src, int width, int height)
+{
+ for (int y = 0; y < height; y += 4)
+ {
+ for (int x = 0; x < width; x += 4)
+ {
+ for (int iy = 0; iy < 4; iy++, src += 4)
+ {
+ for (int ix = 0; ix < 4; ix++)
+ {
+ u32 RGBA = decode5A3(Common::swap16(src[ix]));
+ dst[(y + iy) * width + (x + ix)] = RGBA;
+ }
+ }
+ }
+ }
+}
+} // namespace
diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
index 204c1fe771..e9048fc41d 100644
--- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
+++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp
@@ -1,224 +1,224 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include <stdio.h>
-
-#include "Common.h"
-#include "BannerLoaderWii.h"
-#include "FileUtil.h"
-
-namespace DiscIO
-{
-CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
- : m_pBannerFile(NULL)
- , m_IsValid(false)
-{
- InitLUTTable();
-
- char Filename[260];
- char TitleID[4];
-
- _rFileSystem.GetVolume()->Read(0, 4, (u8*)TitleID);
- sprintf(Filename, FULL_WII_USER_DIR "title/00010000/%02x%02x%02x%02x/data/banner.bin", (u8)TitleID[0], (u8)TitleID[1], (u8)TitleID[2], (u8)TitleID[3]);
-
- // load the opening.bnr
- size_t FileSize = File::GetSize(Filename);
-
- if (FileSize > 0)
- {
- m_pBannerFile = new u8[FileSize];
- FILE* pFile = fopen(Filename, "rb");
- if (pFile != NULL)
- {
- fread(m_pBannerFile, FileSize, 1, pFile);
- fclose(pFile);
- m_IsValid = true;
- }
- }
-}
-
-CBannerLoaderWii::~CBannerLoaderWii()
-{
- if (m_pBannerFile)
- {
- delete [] m_pBannerFile;
- m_pBannerFile = NULL;
- }
-}
-
-
-bool
-CBannerLoaderWii::IsValid()
-{
- return (m_IsValid);
-}
-
-
-bool
-CBannerLoaderWii::GetBanner(u32* _pBannerImage)
-{
- if (!IsValid())
- {
- return false;
- }
-
- SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
-
- static u32 Buffer[192 * 64];
- decode5A3image(Buffer, (u16*)pBanner->m_BannerTexture, 192, 64);
-
- // ugly scaling :)
- for (int y=0; y<32; y++)
- {
- for (int x=0; x<96; x++)
- {
- _pBannerImage[y*96+x] = Buffer[(y*192*2)+(x*2)];
- }
- }
-
-
- return true;
-}
-
-std::string
-CBannerLoaderWii::StupidWideCharToString(u16* _pSrc, size_t _max)
-{
- std::string temp;
-
- u32 offset = 0;
- while (_pSrc[offset] != 0x0000)
- {
- temp += (char)(_pSrc[offset] >> 8);
- offset ++;
-
- if (offset >= _max)
- break;
- }
-
- return temp;
-}
-
-bool
-CBannerLoaderWii::GetName(std::string& _rName, int language)
-{
- if (IsValid())
- {
- SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
-
- // very stupid
- _rName = StupidWideCharToString(pBanner->m_Comment[0], WII_BANNER_COMMENT_SIZE);
- return true;
- }
-
- return true;
-}
-
-
-bool
-CBannerLoaderWii::GetCompany(std::string& _rCompany)
-{
- _rCompany = "N/A";
- return true;
-}
-
-
-bool
-CBannerLoaderWii::GetDescription(std::string& _rDescription)
-{
- if (IsValid())
- {
- SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
-
- // very stupid
- _rDescription = StupidWideCharToString(pBanner->m_Comment[1], WII_BANNER_COMMENT_SIZE);
- return true;
- }
-
- return false;
-}
-
-
-void
-CBannerLoaderWii::InitLUTTable()
-{
- // build LUT Table
- for (int i = 0; i < 8; i++)
- {
- lut3to8[i] = (i * 255) / 7;
- }
-
- for (int i = 0; i < 16; i++)
- {
- lut4to8[i] = (i * 255) / 15;
- }
-
- for (int i = 0; i < 32; i++)
- {
- lut5to8[i] = (i * 255) / 31;
- }
-}
-
-u32
-CBannerLoaderWii::decode5A3(u16 val)
-{
- u32 bannerBGColor = 0x00000000;
-
- int r, g, b, a;
-
- if ((val & 0x8000))
- {
- r = lut5to8[(val >> 10) & 0x1f];
- g = lut5to8[(val >> 5) & 0x1f];
- b = lut5to8[(val) & 0x1f];
- a = 0xFF;
- }
- else
- {
- a = lut3to8[(val >> 12) & 0x7];
- r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
- g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
- b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
- a = 0xFF;
- }
-
- return ((a << 24) | (r << 16) | (g << 8) | b);
-}
-
-
-void
-CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height)
-{
- for (int y = 0; y < height; y += 4)
- {
- for (int x = 0; x < width; x += 4)
- {
- for (int iy = 0; iy < 4; iy++, src += 4)
- {
- for (int ix = 0; ix < 4; ix++)
- {
- u32 RGBA = decode5A3(Common::swap16(src[ix]));
- dst[(y + iy) * width + (x + ix)] = RGBA;
- }
- }
- }
- }
-}
-
-} // namespace
-
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include <stdio.h>
+
+#include "Common.h"
+#include "BannerLoaderWii.h"
+#include "FileUtil.h"
+
+namespace DiscIO
+{
+CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
+ : m_pBannerFile(NULL)
+ , m_IsValid(false)
+{
+ InitLUTTable();
+
+ char Filename[260];
+ char TitleID[4];
+
+ _rFileSystem.GetVolume()->Read(0, 4, (u8*)TitleID);
+ sprintf(Filename, FULL_WII_USER_DIR "title/00010000/%02x%02x%02x%02x/data/banner.bin", (u8)TitleID[0], (u8)TitleID[1], (u8)TitleID[2], (u8)TitleID[3]);
+
+ // load the opening.bnr
+ size_t FileSize = File::GetSize(Filename);
+
+ if (FileSize > 0)
+ {
+ m_pBannerFile = new u8[FileSize];
+ FILE* pFile = fopen(Filename, "rb");
+ if (pFile != NULL)
+ {
+ fread(m_pBannerFile, FileSize, 1, pFile);
+ fclose(pFile);
+ m_IsValid = true;
+ }
+ }
+}
+
+CBannerLoaderWii::~CBannerLoaderWii()
+{
+ if (m_pBannerFile)
+ {
+ delete [] m_pBannerFile;
+ m_pBannerFile = NULL;
+ }
+}
+
+
+bool
+CBannerLoaderWii::IsValid()
+{
+ return (m_IsValid);
+}
+
+
+bool
+CBannerLoaderWii::GetBanner(u32* _pBannerImage)
+{
+ if (!IsValid())
+ {
+ return false;
+ }
+
+ SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
+
+ static u32 Buffer[192 * 64];
+ decode5A3image(Buffer, (u16*)pBanner->m_BannerTexture, 192, 64);
+
+ // ugly scaling :)
+ for (int y=0; y<32; y++)
+ {
+ for (int x=0; x<96; x++)
+ {
+ _pBannerImage[y*96+x] = Buffer[(y*192*2)+(x*2)];
+ }
+ }
+
+
+ return true;
+}
+
+std::string
+CBannerLoaderWii::StupidWideCharToString(u16* _pSrc, size_t _max)
+{
+ std::string temp;
+
+ u32 offset = 0;
+ while (_pSrc[offset] != 0x0000)
+ {
+ temp += (char)(_pSrc[offset] >> 8);
+ offset ++;
+
+ if (offset >= _max)
+ break;
+ }
+
+ return temp;
+}
+
+bool
+CBannerLoaderWii::GetName(std::string& _rName, int language)
+{
+ if (IsValid())
+ {
+ SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
+
+ // very stupid
+ _rName = StupidWideCharToString(pBanner->m_Comment[0], WII_BANNER_COMMENT_SIZE);
+ return true;
+ }
+
+ return true;
+}
+
+
+bool
+CBannerLoaderWii::GetCompany(std::string& _rCompany)
+{
+ _rCompany = "N/A";
+ return true;
+}
+
+
+bool
+CBannerLoaderWii::GetDescription(std::string& _rDescription)
+{
+ if (IsValid())
+ {
+ SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
+
+ // very stupid
+ _rDescription = StupidWideCharToString(pBanner->m_Comment[1], WII_BANNER_COMMENT_SIZE);
+ return true;
+ }
+
+ return false;
+}
+
+
+void
+CBannerLoaderWii::InitLUTTable()
+{
+ // build LUT Table
+ for (int i = 0; i < 8; i++)
+ {
+ lut3to8[i] = (i * 255) / 7;
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ lut4to8[i] = (i * 255) / 15;
+ }
+
+ for (int i = 0; i < 32; i++)
+ {
+ lut5to8[i] = (i * 255) / 31;
+ }
+}
+
+u32
+CBannerLoaderWii::decode5A3(u16 val)
+{
+ u32 bannerBGColor = 0x00000000;
+
+ int r, g, b, a;
+
+ if ((val & 0x8000))
+ {
+ r = lut5to8[(val >> 10) & 0x1f];
+ g = lut5to8[(val >> 5) & 0x1f];
+ b = lut5to8[(val) & 0x1f];
+ a = 0xFF;
+ }
+ else
+ {
+ a = lut3to8[(val >> 12) & 0x7];
+ r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
+ g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
+ b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
+ a = 0xFF;
+ }
+
+ return ((a << 24) | (r << 16) | (g << 8) | b);
+}
+
+
+void
+CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height)
+{
+ for (int y = 0; y < height; y += 4)
+ {
+ for (int x = 0; x < width; x += 4)
+ {
+ for (int iy = 0; iy < 4; iy++, src += 4)
+ {
+ for (int ix = 0; ix < 4; ix++)
+ {
+ u32 RGBA = decode5A3(Common::swap16(src[ix]));
+ dst[(y + iy) * width + (x + ix)] = RGBA;
+ }
+ }
+ }
+ }
+}
+
+} // namespace
+
diff --git a/Source/Core/DiscIO/Src/Blob.cpp b/Source/Core/DiscIO/Src/Blob.cpp
index f26c53ef90..c592c61c33 100644
--- a/Source/Core/DiscIO/Src/Blob.cpp
+++ b/Source/Core/DiscIO/Src/Blob.cpp
@@ -1,110 +1,110 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Common.h"
-#include "FileUtil.h"
-#include "Blob.h"
-#include "CompressedBlob.h"
-#include "FileBlob.h"
-#include "DriveBlob.h"
-#include "MappedFile.h"
-
-namespace DiscIO
-{
-
-// Provides caching and split-operation-to-block-operations facilities.
-// Used for compressed blob reading and direct drive reading.
-
-void SectorReader::SetSectorSize(int blocksize)
-{
- for (int i = 0; i < CACHE_SIZE; i++)
- {
- cache[i] = new u8[blocksize];
- cache_tags[i] = (u64)(s64) - 1;
- }
- m_blocksize = blocksize;
-}
-
-SectorReader::~SectorReader() {
- for (int i = 0; i < CACHE_SIZE; i++)
- delete[] cache[i];
-}
-
-const u8 *SectorReader::GetBlockData(u64 block_num)
-{
- if (cache_tags[0] == block_num)
- {
- return cache[0];
- }
- else
- {
- GetBlock(block_num, cache[0]);
- cache_tags[0] = block_num;
- return cache[0];
- }
-}
-
-bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
-{
- u64 startingBlock = offset / m_blocksize;
- u64 remain = size;
-
- int positionInBlock = (int)(offset % m_blocksize);
- u64 block = startingBlock;
-
- while (remain > 0)
- {
- const u8* data = GetBlockData(block);
- if (!data)
- return false;
-
- u32 toCopy = m_blocksize - positionInBlock;
- if (toCopy >= remain)
- {
- // yay, we are done!
- memcpy(out_ptr, data + positionInBlock, (size_t)remain);
- return true;
- }
- else
- {
- memcpy(out_ptr, data + positionInBlock, toCopy);
- out_ptr += toCopy;
- remain -= toCopy;
- positionInBlock = 0;
- block++;
- }
- }
- return true;
-}
-
-
-IBlobReader* CreateBlobReader(const char* filename)
-{
- //if (strlen(filename) < 4 && filename[1] == ':') // Drive, for sure.
- // return DriveReader::Create(filename);
-
- if (!File::Exists(filename))
- return 0;
-
- if (IsCompressedBlob(filename))
- return CompressedBlobReader::Create(filename);
-
- // Still here? Assume plain file.
- return PlainFileReader::Create(filename);
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "FileUtil.h"
+#include "Blob.h"
+#include "CompressedBlob.h"
+#include "FileBlob.h"
+#include "DriveBlob.h"
+#include "MappedFile.h"
+
+namespace DiscIO
+{
+
+// Provides caching and split-operation-to-block-operations facilities.
+// Used for compressed blob reading and direct drive reading.
+
+void SectorReader::SetSectorSize(int blocksize)
+{
+ for (int i = 0; i < CACHE_SIZE; i++)
+ {
+ cache[i] = new u8[blocksize];
+ cache_tags[i] = (u64)(s64) - 1;
+ }
+ m_blocksize = blocksize;
+}
+
+SectorReader::~SectorReader() {
+ for (int i = 0; i < CACHE_SIZE; i++)
+ delete[] cache[i];
+}
+
+const u8 *SectorReader::GetBlockData(u64 block_num)
+{
+ if (cache_tags[0] == block_num)
+ {
+ return cache[0];
+ }
+ else
+ {
+ GetBlock(block_num, cache[0]);
+ cache_tags[0] = block_num;
+ return cache[0];
+ }
+}
+
+bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
+{
+ u64 startingBlock = offset / m_blocksize;
+ u64 remain = size;
+
+ int positionInBlock = (int)(offset % m_blocksize);
+ u64 block = startingBlock;
+
+ while (remain > 0)
+ {
+ const u8* data = GetBlockData(block);
+ if (!data)
+ return false;
+
+ u32 toCopy = m_blocksize - positionInBlock;
+ if (toCopy >= remain)
+ {
+ // yay, we are done!
+ memcpy(out_ptr, data + positionInBlock, (size_t)remain);
+ return true;
+ }
+ else
+ {
+ memcpy(out_ptr, data + positionInBlock, toCopy);
+ out_ptr += toCopy;
+ remain -= toCopy;
+ positionInBlock = 0;
+ block++;
+ }
+ }
+ return true;
+}
+
+
+IBlobReader* CreateBlobReader(const char* filename)
+{
+ //if (strlen(filename) < 4 && filename[1] == ':') // Drive, for sure.
+ // return DriveReader::Create(filename);
+
+ if (!File::Exists(filename))
+ return 0;
+
+ if (IsCompressedBlob(filename))
+ return CompressedBlobReader::Create(filename);
+
+ // Still here? Assume plain file.
+ return PlainFileReader::Create(filename);
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp
index 370c8b8ede..f424b2c465 100644
--- a/Source/Core/DiscIO/Src/CompressedBlob.cpp
+++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp
@@ -1,342 +1,342 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#ifdef _WIN32
-#include <io.h>
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "Common.h"
-#include "CompressedBlob.h"
-#include "FileUtil.h"
-#include "Hash.h"
-
-#ifdef _WIN32
-#include "../../../../Externals/zlib/zlib.h"
-#else
-// TODO: Include generic zlib.h
-#include "../../../../Externals/zlib/zlib.h"
-#endif
-
-namespace DiscIO
-{
-
-CompressedBlobReader::CompressedBlobReader(const char *filename)
-{
- file = fopen(filename, "rb");
- fseek(file, 0, SEEK_END);
- file_size = ftell(file);
- fseek(file, 0, SEEK_SET);
- fread(&header, sizeof(CompressedBlobHeader), 1, file);
-
- SetSectorSize(header.block_size);
-
- // cache block pointers and hashes
- block_pointers = new u64[header.num_blocks];
- fread(block_pointers, sizeof(u64), header.num_blocks, file);
- hashes = new u32[header.num_blocks];
- fread(hashes, sizeof(u32), header.num_blocks, file);
-
- data_offset = (sizeof(CompressedBlobHeader))
- + (sizeof(u64)) * header.num_blocks // skip block pointers
- + (sizeof(u32)) * header.num_blocks; // skip hashes
-
- // A compressed block is never ever longer than a decompressed block, so just header.block_size should be fine.
- // I still add some safety margin.
- zlib_buffer_size = header.block_size + 64;
- zlib_buffer = new u8[zlib_buffer_size];
- memset(zlib_buffer, 0, zlib_buffer_size);
-}
-
-CompressedBlobReader* CompressedBlobReader::Create(const char* filename)
-{
- if (IsCompressedBlob(filename))
- return new CompressedBlobReader(filename);
- else
- return 0;
-}
-
-CompressedBlobReader::~CompressedBlobReader()
-{
- delete [] zlib_buffer;
- delete [] block_pointers;
- delete [] hashes;
- fclose(file);
- file = 0;
-}
-
-// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
-u64 CompressedBlobReader::GetBlockCompressedSize(u64 block_num) const
-{
- u64 start = block_pointers[block_num];
- if (block_num < header.num_blocks - 1)
- return block_pointers[block_num + 1] - start;
- else if (block_num == header.num_blocks - 1)
- return header.compressed_data_size - start;
- else
- PanicAlert("GetBlockCompressedSize - illegal block number %i", (int)block_num);
- return 0;
-}
-
-void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
-{
- bool uncompressed = false;
- u32 comp_block_size = (u32)GetBlockCompressedSize(block_num);
- u64 offset = block_pointers[block_num] + data_offset;
-
- if (offset & (1ULL << 63))
- {
- if (comp_block_size != header.block_size)
- PanicAlert("Uncompressed block with wrong size");
- uncompressed = true;
- offset &= ~(1ULL << 63);
- }
-
- // clear unused part of zlib buffer. maybe this can be deleted when it works fully.
- memset(zlib_buffer + comp_block_size, 0, zlib_buffer_size - comp_block_size);
-
- fseek(file, offset, SEEK_SET);
- fread(zlib_buffer, 1, comp_block_size, file);
-
- u8* source = zlib_buffer;
- u8* dest = out_ptr;
-
- // First, check hash.
- u32 block_hash = HashAdler32(source, comp_block_size);
- if (block_hash != hashes[block_num])
- PanicAlert("Hash of block %i is %08x instead of %08x. Your ISO is corrupt.",
- block_num, block_hash, hashes[block_num]);
-
- if (uncompressed)
- {
- memcpy(dest, source, comp_block_size);
- }
- else
- {
- z_stream z;
- memset(&z, 0, sizeof(z));
- z.next_in = source;
- z.avail_in = comp_block_size;
- if (z.avail_in > header.block_size)
- {
- PanicAlert("We have a problem");
- }
- z.next_out = dest;
- z.avail_out = header.block_size;
- inflateInit(&z);
- int status = inflate(&z, Z_FULL_FLUSH);
- u32 uncomp_size = header.block_size - z.avail_out;
- if (status != Z_STREAM_END)
- {
- // this seem to fire wrongly from time to time
- // to be sure, don't use compressed isos :P
- PanicAlert("Failure reading block %i - out of data and not at end.", block_num);
- }
- inflateEnd(&z);
- if (uncomp_size != header.block_size)
- PanicAlert("Wrong block size");
- }
-}
-
-bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
- int block_size, CompressCB callback, void* arg)
-{
- if (File::GetSize(infile) > 2000000000ULL) {
- PanicAlert("Sorry - compressing Wii games not yet supported.");
- return false;
- }
-
- if (IsCompressedBlob(infile))
- {
- PanicAlert("%s is already compressed! Cannot compress it further.", infile);
- return false;
- }
-
- FILE* inf = fopen(infile, "rb");
- if (!inf)
- return false;
-
- FILE* f = fopen(outfile, "wb");
- if (!f)
- return false;
-
- callback("Files opened, ready to compress.", 0, arg);
-
- fseek(inf, 0, SEEK_END);
- s64 insize = ftell(inf);
- fseek(inf, 0, SEEK_SET);
- CompressedBlobHeader header;
- header.magic_cookie = kBlobCookie;
- header.sub_type = sub_type;
- header.block_size = block_size;
- header.data_size = insize;
-
- // round upwards!
- header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size);
-
- u64* offsets = new u64[header.num_blocks];
- u32* hashes = new u32[header.num_blocks];
- u8* out_buf = new u8[block_size];
- u8* in_buf = new u8[block_size];
-
- // seek past the header (we will write it at the end)
- fseek(f, sizeof(CompressedBlobHeader), SEEK_CUR);
- // seek past the offset and hash tables (we will write them at the end)
- fseek(f, (sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR);
-
- // Now we are ready to write compressed data!
- u64 position = 0;
- int num_compressed = 0;
- int num_stored = 0;
- for (u32 i = 0; i < header.num_blocks; i++)
- {
- if (i % (header.num_blocks / 1000) == 0)
- {
- u64 inpos = ftell(inf);
- int ratio = 0;
- if (inpos != 0)
- ratio = (int)(100 * position / inpos);
- char temp[512];
- sprintf(temp, "%i of %i blocks. compression ratio %i%%", i, header.num_blocks, ratio);
- callback(temp, (float)i / (float)header.num_blocks, arg);
- }
-
- offsets[i] = position;
- // u64 start = i * header.block_size;
- // u64 size = header.block_size;
- memset(in_buf, 0, header.block_size);
- fread(in_buf, header.block_size, 1, inf);
- z_stream z;
- memset(&z, 0, sizeof(z));
- z.zalloc = Z_NULL;
- z.zfree = Z_NULL;
- z.opaque = Z_NULL;
- z.next_in = in_buf;
- z.avail_in = header.block_size;
- z.next_out = out_buf;
- z.avail_out = block_size;
- int retval = deflateInit(&z, 9);
-
- if (retval != Z_OK)
- {
- PanicAlert("Deflate failed");
- goto cleanup;
- }
-
- int status = deflate(&z, Z_FINISH);
- int comp_size = block_size - z.avail_out;
- if ((status != Z_STREAM_END) || (z.avail_out < 10))
- {
- //PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
- // let's store uncompressed
- offsets[i] |= 0x8000000000000000ULL;
- fwrite(in_buf, block_size, 1, f);
- hashes[i] = HashAdler32(in_buf, block_size);
- position += block_size;
- num_stored++;
- }
- else
- {
- // let's store compressed
- //PanicAlert("Comp %i to %i", block_size, comp_size);
- fwrite(out_buf, comp_size, 1, f);
- hashes[i] = HashAdler32(out_buf, comp_size);
- position += comp_size;
- num_compressed++;
- }
-
- deflateEnd(&z);
- }
-
- header.compressed_data_size = position;
-
- // Okay, go back and fill in headers
- fseek(f, 0, SEEK_SET);
- fwrite(&header, sizeof(header), 1, f);
- fwrite(offsets, sizeof(u64), header.num_blocks, f);
- fwrite(hashes, sizeof(u32), header.num_blocks, f);
-
-cleanup:
- // Cleanup
- delete[] in_buf;
- delete[] out_buf;
- delete[] offsets;
- fclose(f);
- fclose(inf);
- callback("Done compressing disc image.", 1.0f, arg);
- return true;
-}
-
-bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB callback, void* arg)
-{
- if (!IsCompressedBlob(infile))
- {
- PanicAlert("File not compressed");
- return false;
- }
-
- CompressedBlobReader* reader = CompressedBlobReader::Create(infile);
- if (!reader) return false;
-
- FILE* f = fopen(outfile, "wb");
- const CompressedBlobHeader &header = reader->GetHeader();
- u8* buffer = new u8[header.block_size];
-
- for (u64 i = 0; i < header.num_blocks; i++)
- {
- if (i % (header.num_blocks / 100) == 0)
- {
- callback("Unpacking", (float)i / (float)header.num_blocks, arg);
- }
- reader->Read(i * header.block_size, header.block_size, buffer);
- fwrite(buffer, header.block_size, 1, f);
- }
-
- delete[] buffer;
-
-#ifdef _WIN32
- // ector: _chsize sucks, not 64-bit safe
- // F|RES: changed to _chsize_s. i think it is 64-bit safe
- _chsize_s(_fileno(f), (long)header.data_size);
-#else
- ftruncate(fileno(f), header.data_size);
-#endif
- fclose(f);
-
- delete reader;
-
- return true;
-}
-
-bool IsCompressedBlob(const char* filename)
-{
- FILE* f = fopen(filename, "rb");
-
- if (!f)
- return false;
-
- CompressedBlobHeader header;
- fread(&header, sizeof(header), 1, f);
- fclose(f);
- return header.magic_cookie == kBlobCookie;
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "Common.h"
+#include "CompressedBlob.h"
+#include "FileUtil.h"
+#include "Hash.h"
+
+#ifdef _WIN32
+#include "../../../../Externals/zlib/zlib.h"
+#else
+// TODO: Include generic zlib.h
+#include "../../../../Externals/zlib/zlib.h"
+#endif
+
+namespace DiscIO
+{
+
+CompressedBlobReader::CompressedBlobReader(const char *filename)
+{
+ file = fopen(filename, "rb");
+ fseek(file, 0, SEEK_END);
+ file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ fread(&header, sizeof(CompressedBlobHeader), 1, file);
+
+ SetSectorSize(header.block_size);
+
+ // cache block pointers and hashes
+ block_pointers = new u64[header.num_blocks];
+ fread(block_pointers, sizeof(u64), header.num_blocks, file);
+ hashes = new u32[header.num_blocks];
+ fread(hashes, sizeof(u32), header.num_blocks, file);
+
+ data_offset = (sizeof(CompressedBlobHeader))
+ + (sizeof(u64)) * header.num_blocks // skip block pointers
+ + (sizeof(u32)) * header.num_blocks; // skip hashes
+
+ // A compressed block is never ever longer than a decompressed block, so just header.block_size should be fine.
+ // I still add some safety margin.
+ zlib_buffer_size = header.block_size + 64;
+ zlib_buffer = new u8[zlib_buffer_size];
+ memset(zlib_buffer, 0, zlib_buffer_size);
+}
+
+CompressedBlobReader* CompressedBlobReader::Create(const char* filename)
+{
+ if (IsCompressedBlob(filename))
+ return new CompressedBlobReader(filename);
+ else
+ return 0;
+}
+
+CompressedBlobReader::~CompressedBlobReader()
+{
+ delete [] zlib_buffer;
+ delete [] block_pointers;
+ delete [] hashes;
+ fclose(file);
+ file = 0;
+}
+
+// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
+u64 CompressedBlobReader::GetBlockCompressedSize(u64 block_num) const
+{
+ u64 start = block_pointers[block_num];
+ if (block_num < header.num_blocks - 1)
+ return block_pointers[block_num + 1] - start;
+ else if (block_num == header.num_blocks - 1)
+ return header.compressed_data_size - start;
+ else
+ PanicAlert("GetBlockCompressedSize - illegal block number %i", (int)block_num);
+ return 0;
+}
+
+void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
+{
+ bool uncompressed = false;
+ u32 comp_block_size = (u32)GetBlockCompressedSize(block_num);
+ u64 offset = block_pointers[block_num] + data_offset;
+
+ if (offset & (1ULL << 63))
+ {
+ if (comp_block_size != header.block_size)
+ PanicAlert("Uncompressed block with wrong size");
+ uncompressed = true;
+ offset &= ~(1ULL << 63);
+ }
+
+ // clear unused part of zlib buffer. maybe this can be deleted when it works fully.
+ memset(zlib_buffer + comp_block_size, 0, zlib_buffer_size - comp_block_size);
+
+ fseek(file, offset, SEEK_SET);
+ fread(zlib_buffer, 1, comp_block_size, file);
+
+ u8* source = zlib_buffer;
+ u8* dest = out_ptr;
+
+ // First, check hash.
+ u32 block_hash = HashAdler32(source, comp_block_size);
+ if (block_hash != hashes[block_num])
+ PanicAlert("Hash of block %i is %08x instead of %08x. Your ISO is corrupt.",
+ block_num, block_hash, hashes[block_num]);
+
+ if (uncompressed)
+ {
+ memcpy(dest, source, comp_block_size);
+ }
+ else
+ {
+ z_stream z;
+ memset(&z, 0, sizeof(z));
+ z.next_in = source;
+ z.avail_in = comp_block_size;
+ if (z.avail_in > header.block_size)
+ {
+ PanicAlert("We have a problem");
+ }
+ z.next_out = dest;
+ z.avail_out = header.block_size;
+ inflateInit(&z);
+ int status = inflate(&z, Z_FULL_FLUSH);
+ u32 uncomp_size = header.block_size - z.avail_out;
+ if (status != Z_STREAM_END)
+ {
+ // this seem to fire wrongly from time to time
+ // to be sure, don't use compressed isos :P
+ PanicAlert("Failure reading block %i - out of data and not at end.", block_num);
+ }
+ inflateEnd(&z);
+ if (uncomp_size != header.block_size)
+ PanicAlert("Wrong block size");
+ }
+}
+
+bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
+ int block_size, CompressCB callback, void* arg)
+{
+ if (File::GetSize(infile) > 2000000000ULL) {
+ PanicAlert("Sorry - compressing Wii games not yet supported.");
+ return false;
+ }
+
+ if (IsCompressedBlob(infile))
+ {
+ PanicAlert("%s is already compressed! Cannot compress it further.", infile);
+ return false;
+ }
+
+ FILE* inf = fopen(infile, "rb");
+ if (!inf)
+ return false;
+
+ FILE* f = fopen(outfile, "wb");
+ if (!f)
+ return false;
+
+ callback("Files opened, ready to compress.", 0, arg);
+
+ fseek(inf, 0, SEEK_END);
+ s64 insize = ftell(inf);
+ fseek(inf, 0, SEEK_SET);
+ CompressedBlobHeader header;
+ header.magic_cookie = kBlobCookie;
+ header.sub_type = sub_type;
+ header.block_size = block_size;
+ header.data_size = insize;
+
+ // round upwards!
+ header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size);
+
+ u64* offsets = new u64[header.num_blocks];
+ u32* hashes = new u32[header.num_blocks];
+ u8* out_buf = new u8[block_size];
+ u8* in_buf = new u8[block_size];
+
+ // seek past the header (we will write it at the end)
+ fseek(f, sizeof(CompressedBlobHeader), SEEK_CUR);
+ // seek past the offset and hash tables (we will write them at the end)
+ fseek(f, (sizeof(u64) + sizeof(u32)) * header.num_blocks, SEEK_CUR);
+
+ // Now we are ready to write compressed data!
+ u64 position = 0;
+ int num_compressed = 0;
+ int num_stored = 0;
+ for (u32 i = 0; i < header.num_blocks; i++)
+ {
+ if (i % (header.num_blocks / 1000) == 0)
+ {
+ u64 inpos = ftell(inf);
+ int ratio = 0;
+ if (inpos != 0)
+ ratio = (int)(100 * position / inpos);
+ char temp[512];
+ sprintf(temp, "%i of %i blocks. compression ratio %i%%", i, header.num_blocks, ratio);
+ callback(temp, (float)i / (float)header.num_blocks, arg);
+ }
+
+ offsets[i] = position;
+ // u64 start = i * header.block_size;
+ // u64 size = header.block_size;
+ memset(in_buf, 0, header.block_size);
+ fread(in_buf, header.block_size, 1, inf);
+ z_stream z;
+ memset(&z, 0, sizeof(z));
+ z.zalloc = Z_NULL;
+ z.zfree = Z_NULL;
+ z.opaque = Z_NULL;
+ z.next_in = in_buf;
+ z.avail_in = header.block_size;
+ z.next_out = out_buf;
+ z.avail_out = block_size;
+ int retval = deflateInit(&z, 9);
+
+ if (retval != Z_OK)
+ {
+ PanicAlert("Deflate failed");
+ goto cleanup;
+ }
+
+ int status = deflate(&z, Z_FINISH);
+ int comp_size = block_size - z.avail_out;
+ if ((status != Z_STREAM_END) || (z.avail_out < 10))
+ {
+ //PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
+ // let's store uncompressed
+ offsets[i] |= 0x8000000000000000ULL;
+ fwrite(in_buf, block_size, 1, f);
+ hashes[i] = HashAdler32(in_buf, block_size);
+ position += block_size;
+ num_stored++;
+ }
+ else
+ {
+ // let's store compressed
+ //PanicAlert("Comp %i to %i", block_size, comp_size);
+ fwrite(out_buf, comp_size, 1, f);
+ hashes[i] = HashAdler32(out_buf, comp_size);
+ position += comp_size;
+ num_compressed++;
+ }
+
+ deflateEnd(&z);
+ }
+
+ header.compressed_data_size = position;
+
+ // Okay, go back and fill in headers
+ fseek(f, 0, SEEK_SET);
+ fwrite(&header, sizeof(header), 1, f);
+ fwrite(offsets, sizeof(u64), header.num_blocks, f);
+ fwrite(hashes, sizeof(u32), header.num_blocks, f);
+
+cleanup:
+ // Cleanup
+ delete[] in_buf;
+ delete[] out_buf;
+ delete[] offsets;
+ fclose(f);
+ fclose(inf);
+ callback("Done compressing disc image.", 1.0f, arg);
+ return true;
+}
+
+bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB callback, void* arg)
+{
+ if (!IsCompressedBlob(infile))
+ {
+ PanicAlert("File not compressed");
+ return false;
+ }
+
+ CompressedBlobReader* reader = CompressedBlobReader::Create(infile);
+ if (!reader) return false;
+
+ FILE* f = fopen(outfile, "wb");
+ const CompressedBlobHeader &header = reader->GetHeader();
+ u8* buffer = new u8[header.block_size];
+
+ for (u64 i = 0; i < header.num_blocks; i++)
+ {
+ if (i % (header.num_blocks / 100) == 0)
+ {
+ callback("Unpacking", (float)i / (float)header.num_blocks, arg);
+ }
+ reader->Read(i * header.block_size, header.block_size, buffer);
+ fwrite(buffer, header.block_size, 1, f);
+ }
+
+ delete[] buffer;
+
+#ifdef _WIN32
+ // ector: _chsize sucks, not 64-bit safe
+ // F|RES: changed to _chsize_s. i think it is 64-bit safe
+ _chsize_s(_fileno(f), (long)header.data_size);
+#else
+ ftruncate(fileno(f), header.data_size);
+#endif
+ fclose(f);
+
+ delete reader;
+
+ return true;
+}
+
+bool IsCompressedBlob(const char* filename)
+{
+ FILE* f = fopen(filename, "rb");
+
+ if (!f)
+ return false;
+
+ CompressedBlobHeader header;
+ fread(&header, sizeof(header), 1, f);
+ fclose(f);
+ return header.magic_cookie == kBlobCookie;
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp
index aec48d14d0..11f99faada 100644
--- a/Source/Core/DiscIO/Src/DriveBlob.cpp
+++ b/Source/Core/DiscIO/Src/DriveBlob.cpp
@@ -1,25 +1,25 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include "DriveBlob.h"
-
-namespace DiscIO
-{
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include "DriveBlob.h"
+
+namespace DiscIO
+{
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/FileBlob.cpp b/Source/Core/DiscIO/Src/FileBlob.cpp
index 87de28a8da..d3465140ae 100644
--- a/Source/Core/DiscIO/Src/FileBlob.cpp
+++ b/Source/Core/DiscIO/Src/FileBlob.cpp
@@ -1,110 +1,110 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include "Blob.h"
-#include "FileBlob.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-namespace DiscIO
-{
-
-#ifdef _WIN32
-
-PlainFileReader::PlainFileReader(HANDLE hFile_)
-{
- hFile = hFile_;
- DWORD size_low, size_high;
- size_low = GetFileSize(hFile, &size_high);
- size = ((u64)size_low) | ((u64)size_high << 32);
-}
-
-PlainFileReader* PlainFileReader::Create(const char* filename)
-{
- HANDLE hFile = CreateFile(
- filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
- if (hFile != INVALID_HANDLE_VALUE)
- return new PlainFileReader(hFile);
- else
- return 0;
-}
-
-PlainFileReader::~PlainFileReader()
-{
- CloseHandle(hFile);
-}
-
-bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
-{
- LONG offset_high = (LONG)(offset >> 32);
- SetFilePointer(hFile, (DWORD)(offset & 0xFFFFFFFF), &offset_high, FILE_BEGIN);
-
- if (nbytes >= 0x100000000ULL)
- return false; // WTF, does windows really have this limitation?
-
- DWORD unused = 0;
- if (!ReadFile(hFile, out_ptr, DWORD(nbytes & 0xFFFFFFFF), &unused, NULL))
- return false;
- else
- return true;
-}
-
-#else // POSIX
-
-PlainFileReader::PlainFileReader(FILE* file__)
-{
- file_ = file__;
- #if 0
- fseek64(file_, 0, SEEK_END);
- #else
- fseek(file_, 0, SEEK_END); // I don't have fseek64 with gcc 4.3
- #endif
- size = ftell(file_);
- fseek(file_, 0, SEEK_SET);
-}
-
-PlainFileReader* PlainFileReader::Create(const char* filename)
-{
- FILE* file_ = fopen(filename, "rb");
- if (file_)
- return new PlainFileReader(file_);
- else
- return 0;
-}
-
-PlainFileReader::~PlainFileReader()
-{
- fclose(file_);
-}
-
-bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
-{
- int seekStatus = fseek(file_, offset, SEEK_SET);
- if (seekStatus != 0)
- return false;
- size_t bytesRead = fread(out_ptr, 1, nbytes, file_);
- return bytesRead == nbytes;
-}
-
-#endif
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include "Blob.h"
+#include "FileBlob.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace DiscIO
+{
+
+#ifdef _WIN32
+
+PlainFileReader::PlainFileReader(HANDLE hFile_)
+{
+ hFile = hFile_;
+ DWORD size_low, size_high;
+ size_low = GetFileSize(hFile, &size_high);
+ size = ((u64)size_low) | ((u64)size_high << 32);
+}
+
+PlainFileReader* PlainFileReader::Create(const char* filename)
+{
+ HANDLE hFile = CreateFile(
+ filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ return new PlainFileReader(hFile);
+ else
+ return 0;
+}
+
+PlainFileReader::~PlainFileReader()
+{
+ CloseHandle(hFile);
+}
+
+bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
+{
+ LONG offset_high = (LONG)(offset >> 32);
+ SetFilePointer(hFile, (DWORD)(offset & 0xFFFFFFFF), &offset_high, FILE_BEGIN);
+
+ if (nbytes >= 0x100000000ULL)
+ return false; // WTF, does windows really have this limitation?
+
+ DWORD unused = 0;
+ if (!ReadFile(hFile, out_ptr, DWORD(nbytes & 0xFFFFFFFF), &unused, NULL))
+ return false;
+ else
+ return true;
+}
+
+#else // POSIX
+
+PlainFileReader::PlainFileReader(FILE* file__)
+{
+ file_ = file__;
+ #if 0
+ fseek64(file_, 0, SEEK_END);
+ #else
+ fseek(file_, 0, SEEK_END); // I don't have fseek64 with gcc 4.3
+ #endif
+ size = ftell(file_);
+ fseek(file_, 0, SEEK_SET);
+}
+
+PlainFileReader* PlainFileReader::Create(const char* filename)
+{
+ FILE* file_ = fopen(filename, "rb");
+ if (file_)
+ return new PlainFileReader(file_);
+ else
+ return 0;
+}
+
+PlainFileReader::~PlainFileReader()
+{
+ fclose(file_);
+}
+
+bool PlainFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
+{
+ int seekStatus = fseek(file_, offset, SEEK_SET);
+ if (seekStatus != 0)
+ return false;
+ size_t bytesRead = fread(out_ptr, 1, nbytes, file_);
+ return bytesRead == nbytes;
+}
+
+#endif
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/FileHandlerARC.cpp b/Source/Core/DiscIO/Src/FileHandlerARC.cpp
index 17c7270efb..e9a7b96044 100644
--- a/Source/Core/DiscIO/Src/FileHandlerARC.cpp
+++ b/Source/Core/DiscIO/Src/FileHandlerARC.cpp
@@ -1,237 +1,237 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-#include "Common.h"
-
-#include "FileHandlerARC.h"
-#include "StringUtil.h"
-
-
-#define ARC_ID 0x55aa382d
-
-namespace DiscIO
-{
-CARCFile::CARCFile(const u8* _pBuffer, size_t _BufferSize)
- : m_pBuffer(NULL),
- m_Initialized(false)
-{
- m_pBuffer = new u8[_BufferSize];
-
- if (m_pBuffer)
- {
- memcpy(m_pBuffer, _pBuffer, _BufferSize);
- m_Initialized = ParseBuffer();
- }
-}
-
-
-CARCFile::~CARCFile()
-{
- delete [] m_pBuffer;
-}
-
-
-bool
-CARCFile::IsInitialized()
-{
- return(m_Initialized);
-}
-
-
-size_t
-CARCFile::GetFileSize(const std::string& _rFullPath)
-{
- if (!m_Initialized)
- {
- return(0);
- }
-
- const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
-
- if (pFileInfo != NULL)
- {
- return(pFileInfo->m_FileSize);
- }
-
- return(0);
-}
-
-
-size_t
-CARCFile::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
-{
- if (!m_Initialized)
- {
- return(0);
- }
-
- const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
-
- if (pFileInfo == NULL)
- {
- return(0);
- }
-
- if (pFileInfo->m_FileSize > _MaxBufferSize)
- {
- return(0);
- }
-
- memcpy(_pBuffer, &m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize);
- return(pFileInfo->m_FileSize);
-}
-
-
-bool
-CARCFile::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
-{
- if (!m_Initialized)
- {
- return(false);
- }
-
- const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
-
- if (pFileInfo == NULL)
- {
- return(false);
- }
-
- FILE* pFile = fopen(_rExportFilename.c_str(), "wb");
-
- if (pFile == NULL)
- {
- return(false);
- }
-
- fwrite(&m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize, 1, pFile);
- fclose(pFile);
- return(true);
-}
-
-
-bool
-CARCFile::ExportAllFiles(const std::string& _rFullPath)
-{
- return(false);
-}
-
-
-bool
-CARCFile::ParseBuffer()
-{
- // check ID
- u32 ID = Common::swap32(*(u32*)(m_pBuffer));
-
- if (ID != ARC_ID)
- {
- return(false);
- }
-
- // read header
- u32 FSTOffset = Common::swap32(*(u32*)(m_pBuffer + 0x4));
- //u32 FSTSize = Common::swap32(*(u32*)(m_pBuffer + 0x8));
- //u32 FileOffset = Common::swap32(*(u32*)(m_pBuffer + 0xC));
-
- // read all file infos
- SFileInfo Root;
- Root.m_NameOffset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x0));
- Root.m_Offset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x4));
- Root.m_FileSize = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x8));
-
- if (Root.IsDirectory())
- {
- m_FileInfoVector.resize(Root.m_FileSize);
- const char* szNameTable = (char*)(m_pBuffer + FSTOffset);
-
- for (size_t i = 0; i < m_FileInfoVector.size(); i++)
- {
- u8* Offset = m_pBuffer + FSTOffset + (i * 0xC);
- m_FileInfoVector[i].m_NameOffset = Common::swap32(*(u32*)(Offset + 0x0));
- m_FileInfoVector[i].m_Offset = Common::swap32(*(u32*)(Offset + 0x4));
- m_FileInfoVector[i].m_FileSize = Common::swap32(*(u32*)(Offset + 0x8));
-
- szNameTable += 0xC;
- }
-
- BuildFilenames(1, m_FileInfoVector.size(), NULL, szNameTable);
- }
-
- return(true);
-}
-
-
-size_t
-CARCFile::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, const char* _szNameTable)
-{
- size_t CurrentIndex = _FirstIndex;
-
- while (CurrentIndex < _LastIndex)
- {
- SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
- int uOffset = rFileInfo.m_NameOffset & 0xFFFFFF;
-
- // check next index
- if (rFileInfo.IsDirectory())
- {
- // this is a directory, build up the new szDirectory
- if (_szDirectory != NULL)
- {
- sprintf(rFileInfo.m_FullPath, "%s%s\\", _szDirectory, &_szNameTable[uOffset]);
- }
- else
- {
- sprintf(rFileInfo.m_FullPath, "%s\\", &_szNameTable[uOffset]);
- }
-
- CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo.m_FileSize, rFileInfo.m_FullPath, _szNameTable);
- }
- else
- {
- // this is a filename
- if (_szDirectory != NULL)
- {
- sprintf(rFileInfo.m_FullPath, "%s%s", _szDirectory, &_szNameTable[uOffset]);
- }
- else
- {
- sprintf(rFileInfo.m_FullPath, "%s", &_szNameTable[uOffset]);
- }
-
- CurrentIndex++;
- }
- }
-
- return(CurrentIndex);
-}
-
-
-const SFileInfo*
-CARCFile::FindFileInfo(std::string _rFullPath) const
-{
- for (size_t i = 0; i < m_FileInfoVector.size(); i++)
- {
- if (!strcasecmp(m_FileInfoVector[i].m_FullPath, _rFullPath.c_str()))
- {
- return(&m_FileInfoVector[i]);
- }
- }
-
- return(NULL);
-}
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+#include "Common.h"
+
+#include "FileHandlerARC.h"
+#include "StringUtil.h"
+
+
+#define ARC_ID 0x55aa382d
+
+namespace DiscIO
+{
+CARCFile::CARCFile(const u8* _pBuffer, size_t _BufferSize)
+ : m_pBuffer(NULL),
+ m_Initialized(false)
+{
+ m_pBuffer = new u8[_BufferSize];
+
+ if (m_pBuffer)
+ {
+ memcpy(m_pBuffer, _pBuffer, _BufferSize);
+ m_Initialized = ParseBuffer();
+ }
+}
+
+
+CARCFile::~CARCFile()
+{
+ delete [] m_pBuffer;
+}
+
+
+bool
+CARCFile::IsInitialized()
+{
+ return(m_Initialized);
+}
+
+
+size_t
+CARCFile::GetFileSize(const std::string& _rFullPath)
+{
+ if (!m_Initialized)
+ {
+ return(0);
+ }
+
+ const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
+
+ if (pFileInfo != NULL)
+ {
+ return(pFileInfo->m_FileSize);
+ }
+
+ return(0);
+}
+
+
+size_t
+CARCFile::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
+{
+ if (!m_Initialized)
+ {
+ return(0);
+ }
+
+ const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
+
+ if (pFileInfo == NULL)
+ {
+ return(0);
+ }
+
+ if (pFileInfo->m_FileSize > _MaxBufferSize)
+ {
+ return(0);
+ }
+
+ memcpy(_pBuffer, &m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize);
+ return(pFileInfo->m_FileSize);
+}
+
+
+bool
+CARCFile::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
+{
+ if (!m_Initialized)
+ {
+ return(false);
+ }
+
+ const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
+
+ if (pFileInfo == NULL)
+ {
+ return(false);
+ }
+
+ FILE* pFile = fopen(_rExportFilename.c_str(), "wb");
+
+ if (pFile == NULL)
+ {
+ return(false);
+ }
+
+ fwrite(&m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize, 1, pFile);
+ fclose(pFile);
+ return(true);
+}
+
+
+bool
+CARCFile::ExportAllFiles(const std::string& _rFullPath)
+{
+ return(false);
+}
+
+
+bool
+CARCFile::ParseBuffer()
+{
+ // check ID
+ u32 ID = Common::swap32(*(u32*)(m_pBuffer));
+
+ if (ID != ARC_ID)
+ {
+ return(false);
+ }
+
+ // read header
+ u32 FSTOffset = Common::swap32(*(u32*)(m_pBuffer + 0x4));
+ //u32 FSTSize = Common::swap32(*(u32*)(m_pBuffer + 0x8));
+ //u32 FileOffset = Common::swap32(*(u32*)(m_pBuffer + 0xC));
+
+ // read all file infos
+ SFileInfo Root;
+ Root.m_NameOffset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x0));
+ Root.m_Offset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x4));
+ Root.m_FileSize = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x8));
+
+ if (Root.IsDirectory())
+ {
+ m_FileInfoVector.resize(Root.m_FileSize);
+ const char* szNameTable = (char*)(m_pBuffer + FSTOffset);
+
+ for (size_t i = 0; i < m_FileInfoVector.size(); i++)
+ {
+ u8* Offset = m_pBuffer + FSTOffset + (i * 0xC);
+ m_FileInfoVector[i].m_NameOffset = Common::swap32(*(u32*)(Offset + 0x0));
+ m_FileInfoVector[i].m_Offset = Common::swap32(*(u32*)(Offset + 0x4));
+ m_FileInfoVector[i].m_FileSize = Common::swap32(*(u32*)(Offset + 0x8));
+
+ szNameTable += 0xC;
+ }
+
+ BuildFilenames(1, m_FileInfoVector.size(), NULL, szNameTable);
+ }
+
+ return(true);
+}
+
+
+size_t
+CARCFile::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, const char* _szNameTable)
+{
+ size_t CurrentIndex = _FirstIndex;
+
+ while (CurrentIndex < _LastIndex)
+ {
+ SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
+ int uOffset = rFileInfo.m_NameOffset & 0xFFFFFF;
+
+ // check next index
+ if (rFileInfo.IsDirectory())
+ {
+ // this is a directory, build up the new szDirectory
+ if (_szDirectory != NULL)
+ {
+ sprintf(rFileInfo.m_FullPath, "%s%s\\", _szDirectory, &_szNameTable[uOffset]);
+ }
+ else
+ {
+ sprintf(rFileInfo.m_FullPath, "%s\\", &_szNameTable[uOffset]);
+ }
+
+ CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo.m_FileSize, rFileInfo.m_FullPath, _szNameTable);
+ }
+ else
+ {
+ // this is a filename
+ if (_szDirectory != NULL)
+ {
+ sprintf(rFileInfo.m_FullPath, "%s%s", _szDirectory, &_szNameTable[uOffset]);
+ }
+ else
+ {
+ sprintf(rFileInfo.m_FullPath, "%s", &_szNameTable[uOffset]);
+ }
+
+ CurrentIndex++;
+ }
+ }
+
+ return(CurrentIndex);
+}
+
+
+const SFileInfo*
+CARCFile::FindFileInfo(std::string _rFullPath) const
+{
+ for (size_t i = 0; i < m_FileInfoVector.size(); i++)
+ {
+ if (!strcasecmp(m_FileInfoVector[i].m_FullPath, _rFullPath.c_str()))
+ {
+ return(&m_FileInfoVector[i]);
+ }
+ }
+
+ return(NULL);
+}
+} // namespace
diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
index a06b55836e..13376e447c 100644
--- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp
@@ -1,249 +1,249 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-#include "Common.h"
-
-#include <string>
-
-#include "FileSystemGCWii.h"
-#include "StringUtil.h"
-
-namespace DiscIO
-{
-CFileSystemGCWii::CFileSystemGCWii(const IVolume *_rVolume)
- : IFileSystem(_rVolume),
- m_Initialized(false),
- m_OffsetShift(0)
-{
- m_Initialized = InitFileSystem();
-}
-
-
-CFileSystemGCWii::~CFileSystemGCWii()
-{
-}
-
-bool CFileSystemGCWii::IsInitialized() const
-{
- return m_Initialized;
-}
-
-u64 CFileSystemGCWii::GetFileSize(const char* _rFullPath) const
-{
- if (!m_Initialized)
- return 0;
-
- const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
-
- if (pFileInfo != NULL)
- return pFileInfo->m_FileSize;
-
- return 0;
-}
-
-const char* CFileSystemGCWii::GetFileName(u64 _Address) const
-{
- for (size_t i = 0; i < m_FileInfoVector.size(); i++)
- {
- if ((m_FileInfoVector[i].m_Offset <= _Address) &&
- ((m_FileInfoVector[i].m_Offset + m_FileInfoVector[i].m_FileSize) > _Address))
- {
- return m_FileInfoVector[i].m_FullPath;
- }
- }
-
- return NULL;
-}
-
-u64 CFileSystemGCWii::ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _MaxBufferSize) const
-{
- if (!m_Initialized)
- return 0;
-
- const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
- if (pFileInfo == NULL)
- return 0;
-
- if (pFileInfo->m_FileSize > _MaxBufferSize)
- return 0;
-
- m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer);
- return pFileInfo->m_FileSize;
-}
-
-bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFilename) const
-{
- size_t filesize = GetFileSize(_rFullPath);
-
- if (filesize == 0)
- return false;
-
- u8* buffer = new u8[filesize];
-
- if (!ReadFile(_rFullPath, buffer, filesize))
- {
- delete[] buffer;
- return false;
- }
-
- FILE* f = fopen(_rExportFilename, "wb");
-
- if (f)
- {
- fwrite(buffer, filesize, 1, f);
- fclose(f);
- delete[] buffer;
- return true;
- }
-
- delete[] buffer;
- return false;
-}
-
-bool CFileSystemGCWii::ExportAllFiles(const char* _rFullPath) const
-{
- return false;
-}
-
-u32 CFileSystemGCWii::Read32(u64 _Offset) const
-{
- u32 Temp = 0;
- m_rVolume->Read(_Offset, 4, (u8*)&Temp);
- return Common::swap32(Temp);
-}
-
-void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const
-{
- m_rVolume->Read(_Offset, 255, (u8*)Filename);
-}
-
-size_t CFileSystemGCWii::GetFileList(std::vector<const SFileInfo *> &_rFilenames) const
-{
- if (_rFilenames.size())
- PanicAlert("GetFileList : input list has contents?");
- _rFilenames.clear();
- _rFilenames.reserve(m_FileInfoVector.size());
- for (size_t i = 0; i < m_FileInfoVector.size(); i++)
- _rFilenames.push_back(&m_FileInfoVector[i]);
- return m_FileInfoVector.size();
-}
-
-const SFileInfo* CFileSystemGCWii::FindFileInfo(const char* _rFullPath) const
-{
- for (size_t i = 0; i < m_FileInfoVector.size(); i++)
- {
- if (!strcasecmp(m_FileInfoVector[i].m_FullPath, _rFullPath))
- return &m_FileInfoVector[i];
- }
-
- return NULL;
-}
-
-bool CFileSystemGCWii::InitFileSystem()
-{
- if (Read32(0x18) == 0x5D1C9EA3)
- {
- m_OffsetShift = 2; // Wii file system
- }
- else if (Read32(0x1c) == 0xC2339F3D)
- {
- m_OffsetShift = 0; // GC file system
- }
- else
- {
- return false;
- }
-
- // read the whole FST
- u64 FSTOffset = (u64)Read32(0x424) << m_OffsetShift;
- // u32 FSTSize = Read32(0x428);
- // u32 FSTMaxSize = Read32(0x42C);
-
-
- // read all fileinfos
- SFileInfo Root;
- Root.m_NameOffset = Read32(FSTOffset + 0x0);
- Root.m_Offset = (u64)Read32(FSTOffset + 0x4) << m_OffsetShift;
- Root.m_FileSize = Read32(FSTOffset + 0x8);
-
- if (Root.IsDirectory())
- {
- if (m_FileInfoVector.size())
- PanicAlert("Wtf?");
- u64 NameTableOffset = FSTOffset;
-
- m_FileInfoVector.reserve(Root.m_FileSize);
- for (u32 i = 0; i < Root.m_FileSize; i++)
- {
- SFileInfo sfi;
- u64 Offset = FSTOffset + (i * 0xC);
- sfi.m_NameOffset = Read32(Offset + 0x0);
- sfi.m_Offset = (u64)Read32(Offset + 0x4) << m_OffsetShift;
- sfi.m_FileSize = Read32(Offset + 0x8);
-
- m_FileInfoVector.push_back(sfi);
- NameTableOffset += 0xC;
- }
-
- BuildFilenames(1, m_FileInfoVector.size(), NULL, NameTableOffset);
- }
-
- return true;
-}
-
-// Changed this stuff from C++ string to C strings for speed in debug mode. Doesn't matter in release, but
-// std::string is SLOW in debug mode.
-size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset)
-{
- size_t CurrentIndex = _FirstIndex;
-
- while (CurrentIndex < _LastIndex)
- {
- SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex];
- u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF);
- char filename[512];
- memset(filename, 0, sizeof(filename));
- GetStringFromOffset(uOffset, filename);
-
- // 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);
- else
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s\\", filename);
-
- CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset);
- }
- else
- {
- // this is a filename
- if (_szDirectory != NULL)
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename);
- else
- CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename);
-
- CurrentIndex++;
- }
- }
-
- return CurrentIndex;
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+#include "Common.h"
+
+#include <string>
+
+#include "FileSystemGCWii.h"
+#include "StringUtil.h"
+
+namespace DiscIO
+{
+CFileSystemGCWii::CFileSystemGCWii(const IVolume *_rVolume)
+ : IFileSystem(_rVolume),
+ m_Initialized(false),
+ m_OffsetShift(0)
+{
+ m_Initialized = InitFileSystem();
+}
+
+
+CFileSystemGCWii::~CFileSystemGCWii()
+{
+}
+
+bool CFileSystemGCWii::IsInitialized() const
+{
+ return m_Initialized;
+}
+
+u64 CFileSystemGCWii::GetFileSize(const char* _rFullPath) const
+{
+ if (!m_Initialized)
+ return 0;
+
+ const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
+
+ if (pFileInfo != NULL)
+ return pFileInfo->m_FileSize;
+
+ return 0;
+}
+
+const char* CFileSystemGCWii::GetFileName(u64 _Address) const
+{
+ for (size_t i = 0; i < m_FileInfoVector.size(); i++)
+ {
+ if ((m_FileInfoVector[i].m_Offset <= _Address) &&
+ ((m_FileInfoVector[i].m_Offset + m_FileInfoVector[i].m_FileSize) > _Address))
+ {
+ return m_FileInfoVector[i].m_FullPath;
+ }
+ }
+
+ return NULL;
+}
+
+u64 CFileSystemGCWii::ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _MaxBufferSize) const
+{
+ if (!m_Initialized)
+ return 0;
+
+ const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
+ if (pFileInfo == NULL)
+ return 0;
+
+ if (pFileInfo->m_FileSize > _MaxBufferSize)
+ return 0;
+
+ m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer);
+ return pFileInfo->m_FileSize;
+}
+
+bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFilename) const
+{
+ size_t filesize = GetFileSize(_rFullPath);
+
+ if (filesize == 0)
+ return false;
+
+ u8* buffer = new u8[filesize];
+
+ if (!ReadFile(_rFullPath, buffer, filesize))
+ {
+ delete[] buffer;
+ return false;
+ }
+
+ FILE* f = fopen(_rExportFilename, "wb");
+
+ if (f)
+ {
+ fwrite(buffer, filesize, 1, f);
+ fclose(f);
+ delete[] buffer;
+ return true;
+ }
+
+ delete[] buffer;
+ return false;
+}
+
+bool CFileSystemGCWii::ExportAllFiles(const char* _rFullPath) const
+{
+ return false;
+}
+
+u32 CFileSystemGCWii::Read32(u64 _Offset) const
+{
+ u32 Temp = 0;
+ m_rVolume->Read(_Offset, 4, (u8*)&Temp);
+ return Common::swap32(Temp);
+}
+
+void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const
+{
+ m_rVolume->Read(_Offset, 255, (u8*)Filename);
+}
+
+size_t CFileSystemGCWii::GetFileList(std::vector<const SFileInfo *> &_rFilenames) const
+{
+ if (_rFilenames.size())
+ PanicAlert("GetFileList : input list has contents?");
+ _rFilenames.clear();
+ _rFilenames.reserve(m_FileInfoVector.size());
+ for (size_t i = 0; i < m_FileInfoVector.size(); i++)
+ _rFilenames.push_back(&m_FileInfoVector[i]);
+ return m_FileInfoVector.size();
+}
+
+const SFileInfo* CFileSystemGCWii::FindFileInfo(const char* _rFullPath) const
+{
+ for (size_t i = 0; i < m_FileInfoVector.size(); i++)
+ {
+ if (!strcasecmp(m_FileInfoVector[i].m_FullPath, _rFullPath))
+ return &m_FileInfoVector[i];
+ }
+
+ return NULL;
+}
+
+bool CFileSystemGCWii::InitFileSystem()
+{
+ if (Read32(0x18) == 0x5D1C9EA3)
+ {
+ m_OffsetShift = 2; // Wii file system
+ }
+ else if (Read32(0x1c) == 0xC2339F3D)
+ {
+ m_OffsetShift = 0; // GC file system
+ }
+ else
+ {
+ return false;
+ }
+
+ // read the whole FST
+ u64 FSTOffset = (u64)Read32(0x424) << m_OffsetShift;
+ // u32 FSTSize = Read32(0x428);
+ // u32 FSTMaxSize = Read32(0x42C);
+
+
+ // read all fileinfos
+ SFileInfo Root;
+ Root.m_NameOffset = Read32(FSTOffset + 0x0);
+ Root.m_Offset = (u64)Read32(FSTOffset + 0x4) << m_OffsetShift;
+ Root.m_FileSize = Read32(FSTOffset + 0x8);
+
+ if (Root.IsDirectory())
+ {
+ if (m_FileInfoVector.size())
+ PanicAlert("Wtf?");
+ u64 NameTableOffset = FSTOffset;
+
+ m_FileInfoVector.reserve(Root.m_FileSize);
+ for (u32 i = 0; i < Root.m_FileSize; i++)
+ {
+ SFileInfo sfi;
+ u64 Offset = FSTOffset + (i * 0xC);
+ sfi.m_NameOffset = Read32(Offset + 0x0);
+ sfi.m_Offset = (u64)Read32(Offset + 0x4) << m_OffsetShift;
+ sfi.m_FileSize = Read32(Offset + 0x8);
+
+ m_FileInfoVector.push_back(sfi);
+ NameTableOffset += 0xC;
+ }
+
+ BuildFilenames(1, m_FileInfoVector.size(), NULL, NameTableOffset);
+ }
+
+ return true;
+}
+
+// Changed this stuff from C++ string to C strings for speed in debug mode. Doesn't matter in release, but
+// std::string is SLOW in debug mode.
+size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset)
+{
+ size_t CurrentIndex = _FirstIndex;
+
+ while (CurrentIndex < _LastIndex)
+ {
+ SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex];
+ u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF);
+ char filename[512];
+ memset(filename, 0, sizeof(filename));
+ GetStringFromOffset(uOffset, filename);
+
+ // 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);
+ else
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s\\", filename);
+
+ CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset);
+ }
+ else
+ {
+ // this is a filename
+ if (_szDirectory != NULL)
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename);
+ else
+ CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename);
+
+ CurrentIndex++;
+ }
+ }
+
+ return CurrentIndex;
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/Filesystem.cpp b/Source/Core/DiscIO/Src/Filesystem.cpp
index 39bf82e822..5118c8e7b2 100644
--- a/Source/Core/DiscIO/Src/Filesystem.cpp
+++ b/Source/Core/DiscIO/Src/Filesystem.cpp
@@ -1,50 +1,50 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-#include "Filesystem.h"
-
-#include "VolumeCreator.h"
-#include "FileSystemGCWii.h"
-
-namespace DiscIO
-{
-IFileSystem::IFileSystem(const IVolume *_rVolume)
- : m_rVolume(_rVolume)
-{}
-
-
-IFileSystem::~IFileSystem()
-{}
-
-
-IFileSystem* CreateFileSystem(const IVolume* _rVolume)
-{
- IFileSystem* pFileSystem = new CFileSystemGCWii(_rVolume);
-
- if (!pFileSystem)
- return 0;
-
- if (!pFileSystem->IsInitialized())
- {
- delete pFileSystem;
- pFileSystem = NULL;
- }
-
- return pFileSystem;
-}
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+#include "Filesystem.h"
+
+#include "VolumeCreator.h"
+#include "FileSystemGCWii.h"
+
+namespace DiscIO
+{
+IFileSystem::IFileSystem(const IVolume *_rVolume)
+ : m_rVolume(_rVolume)
+{}
+
+
+IFileSystem::~IFileSystem()
+{}
+
+
+IFileSystem* CreateFileSystem(const IVolume* _rVolume)
+{
+ IFileSystem* pFileSystem = new CFileSystemGCWii(_rVolume);
+
+ if (!pFileSystem)
+ return 0;
+
+ if (!pFileSystem->IsInitialized())
+ {
+ delete pFileSystem;
+ pFileSystem = NULL;
+ }
+
+ return pFileSystem;
+}
+} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeCreator.cpp b/Source/Core/DiscIO/Src/VolumeCreator.cpp
index 319af6b7d9..2ff5e8471b 100644
--- a/Source/Core/DiscIO/Src/VolumeCreator.cpp
+++ b/Source/Core/DiscIO/Src/VolumeCreator.cpp
@@ -1,262 +1,262 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <vector>
-
-#include "AES/aes.h"
-
-#include "VolumeCreator.h"
-
-#include "Volume.h"
-#include "VolumeDirectory.h"
-#include "VolumeGC.h"
-#include "VolumeWiiCrypted.h"
-
-#include "Hash.h"
-
-namespace DiscIO
-{
-enum EDiscType
-{
- DISC_TYPE_UNK,
- DISC_TYPE_WII,
- DISC_TYPE_WII_CONTAINER,
- DISC_TYPE_GC
-};
-
-#ifndef _WIN32
-struct SPartition
-{
- u64 Offset;
- u32 Type;
-}; //gcc 4.3 cries if it's local
-#endif
-
-class CBlobBigEndianReader
-{
-public:
- CBlobBigEndianReader(IBlobReader& _rReader) : m_rReader(_rReader) {}
-
- u32 Read32(u64 _Offset)
- {
- u32 Temp;
- m_rReader.Read(_Offset, 4, (u8*)&Temp);
- return(Common::swap32(Temp));
- }
-
-private:
- IBlobReader& m_rReader;
-};
-
-unsigned char g_MasterKey[16];
-bool g_MasterKeyInit = false;
-
-IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType);
-EDiscType GetDiscType(IBlobReader& _rReader);
-
-IVolume* CreateVolumeFromFilename(const std::string& _rFilename)
-{
- IBlobReader* pReader = CreateBlobReader(_rFilename.c_str());
-
- if (pReader == NULL)
- return NULL;
-
- switch (GetDiscType(*pReader))
- {
- case DISC_TYPE_WII:
- case DISC_TYPE_GC:
- return new CVolumeGC(pReader);
-
- case DISC_TYPE_WII_CONTAINER:
- {
- IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, 0);
-
- if (pVolume == NULL)
- {
- delete pReader;
- }
-
- return(pVolume);
- }
- break;
-
- case DISC_TYPE_UNK:
- default:
- delete pReader;
- return NULL;
- }
-
- // unreachable code
- return NULL;
-}
-
-IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii)
-{
- if (CVolumeDirectory::IsValidDirectory(_rDirectory))
- return new CVolumeDirectory(_rDirectory, _bIsWii);
-
- return NULL;
-}
-
-bool IsVolumeWiiDisc(const IVolume *_rVolume)
-{
- u32 MagicWord = 0;
- _rVolume->Read(0x18, 4, (u8*)&MagicWord);
-
- return (Common::swap32(MagicWord) == 0x5D1C9EA3);
-}
-
-IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType)
-{
- if (!g_MasterKeyInit)
- {
- FILE* pT = fopen(WII_MASTERKEY_FILE, "rb");
- if (pT == NULL)
- {
- if(PanicYesNo("Can't open '" WII_MASTERKEY_FILE "'.\n If you know the key, now it's the time to paste it into '"
- WII_MASTERKEY_FILE_HEX "' before pressing [YES]."))
- {
- pT = fopen(WII_MASTERKEY_FILE_HEX, "r");
- if(pT==NULL){
- PanicAlert("could not open " WII_MASTERKEY_FILE_HEX );
- return NULL;
- }
-
- static char hexkey[32];
- if(fread(hexkey,1,32,pT)<32)
- {
- PanicAlert(WII_MASTERKEY_FILE_HEX " is not the right size" );
- fclose(pT);
- return NULL;
- }
- fclose(pT);
-
- static char binkey[16];
- char *t=hexkey;
- for(int i=0;i<16;i++)
- {
- char h[3]={*(t++),*(t++),0};
- binkey[i] = strtol(h,NULL,16);
- }
-
- pT = fopen(WII_MASTERKEY_FILE, "wb");
- if(pT==NULL){
- PanicAlert("could not open/make '" WII_MASTERKEY_FILE "' for writing!");
- return NULL;
- }
-
- fwrite(binkey,16,1,pT);
- fclose(pT);
-
- pT = fopen(WII_MASTERKEY_FILE, "rb");
- if(pT==NULL){
- PanicAlert("could not open '" WII_MASTERKEY_FILE "' for reading!\n did the file get deleted or locked after converting?");
- return NULL;
- }
- }
- else
- return NULL;
- }
-
- fread(g_MasterKey, 16, 1, pT);
- fclose(pT);
- const u32 keyhash = 0x4bc30936;
- u32 hash = HashAdler32(g_MasterKey, 16);
- if (hash != keyhash)
- PanicAlert("Your Wii disc decryption key is bad.", keyhash, hash);
- else
- g_MasterKeyInit = true;
- }
-
- CBlobBigEndianReader Reader(_rReader);
-
- u32 numPartitions = Reader.Read32(0x40000);
- u64 PartitionsOffset = (u64)Reader.Read32(0x40004) << 2;
- #ifdef _WIN32
- struct SPartition
- {
- u64 Offset;
- u32 Type;
- };
- #endif
- std::vector<SPartition> PartitionsVec;
-
- // read all partitions
- for (u32 i = 0; i < numPartitions; i++)
- {
- SPartition Partition;
- Partition.Offset = ((u64)Reader.Read32(PartitionsOffset + (i * 8) + 0)) << 2;
- Partition.Type = Reader.Read32(PartitionsOffset + (i * 8) + 4);
- PartitionsVec.push_back(Partition);
- }
-
- // find the partition with the game... type == 1 is prolly the firmware update partition
- for (size_t i = 0; i < PartitionsVec.size(); i++)
- {
- const SPartition& rPartition = PartitionsVec[i];
-
- if (rPartition.Type == _VolumeType)
- {
- u8 SubKey[16];
- _rReader.Read(rPartition.Offset + 0x1bf, 16, SubKey);
-
- u8 IV[16];
- memset(IV, 0, 16);
- _rReader.Read(rPartition.Offset + 0x44c, 8, IV);
-
- AES_KEY AES_KEY;
- AES_set_decrypt_key(g_MasterKey, 128, &AES_KEY);
-
- u8 VolumeKey[16];
- AES_cbc_encrypt(SubKey, VolumeKey, 16, &AES_KEY, IV, AES_DECRYPT);
-
- return new CVolumeWiiCrypted(&_rReader, rPartition.Offset + 0x20000, VolumeKey);
- }
- }
-
- return NULL;
-}
-
-EDiscType GetDiscType(IBlobReader& _rReader)
-{
- CBlobBigEndianReader Reader(_rReader);
-
- // check for wii
- {
- u32 MagicWord = Reader.Read32(0x18);
-
- if (MagicWord == 0x5D1C9EA3)
- {
- if (Reader.Read32(0x60) != 0)
- return(DISC_TYPE_WII);
- else
- return(DISC_TYPE_WII_CONTAINER);
- }
- }
-
- // check for GC
- {
- u32 MagicWord = Reader.Read32(0x1C);
-
- if (MagicWord == 0xC2339F3D)
- return(DISC_TYPE_GC);
- }
-
- return DISC_TYPE_UNK;
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include <vector>
+
+#include "AES/aes.h"
+
+#include "VolumeCreator.h"
+
+#include "Volume.h"
+#include "VolumeDirectory.h"
+#include "VolumeGC.h"
+#include "VolumeWiiCrypted.h"
+
+#include "Hash.h"
+
+namespace DiscIO
+{
+enum EDiscType
+{
+ DISC_TYPE_UNK,
+ DISC_TYPE_WII,
+ DISC_TYPE_WII_CONTAINER,
+ DISC_TYPE_GC
+};
+
+#ifndef _WIN32
+struct SPartition
+{
+ u64 Offset;
+ u32 Type;
+}; //gcc 4.3 cries if it's local
+#endif
+
+class CBlobBigEndianReader
+{
+public:
+ CBlobBigEndianReader(IBlobReader& _rReader) : m_rReader(_rReader) {}
+
+ u32 Read32(u64 _Offset)
+ {
+ u32 Temp;
+ m_rReader.Read(_Offset, 4, (u8*)&Temp);
+ return(Common::swap32(Temp));
+ }
+
+private:
+ IBlobReader& m_rReader;
+};
+
+unsigned char g_MasterKey[16];
+bool g_MasterKeyInit = false;
+
+IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType);
+EDiscType GetDiscType(IBlobReader& _rReader);
+
+IVolume* CreateVolumeFromFilename(const std::string& _rFilename)
+{
+ IBlobReader* pReader = CreateBlobReader(_rFilename.c_str());
+
+ if (pReader == NULL)
+ return NULL;
+
+ switch (GetDiscType(*pReader))
+ {
+ case DISC_TYPE_WII:
+ case DISC_TYPE_GC:
+ return new CVolumeGC(pReader);
+
+ case DISC_TYPE_WII_CONTAINER:
+ {
+ IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, 0);
+
+ if (pVolume == NULL)
+ {
+ delete pReader;
+ }
+
+ return(pVolume);
+ }
+ break;
+
+ case DISC_TYPE_UNK:
+ default:
+ delete pReader;
+ return NULL;
+ }
+
+ // unreachable code
+ return NULL;
+}
+
+IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii)
+{
+ if (CVolumeDirectory::IsValidDirectory(_rDirectory))
+ return new CVolumeDirectory(_rDirectory, _bIsWii);
+
+ return NULL;
+}
+
+bool IsVolumeWiiDisc(const IVolume *_rVolume)
+{
+ u32 MagicWord = 0;
+ _rVolume->Read(0x18, 4, (u8*)&MagicWord);
+
+ return (Common::swap32(MagicWord) == 0x5D1C9EA3);
+}
+
+IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType)
+{
+ if (!g_MasterKeyInit)
+ {
+ FILE* pT = fopen(WII_MASTERKEY_FILE, "rb");
+ if (pT == NULL)
+ {
+ if(PanicYesNo("Can't open '" WII_MASTERKEY_FILE "'.\n If you know the key, now it's the time to paste it into '"
+ WII_MASTERKEY_FILE_HEX "' before pressing [YES]."))
+ {
+ pT = fopen(WII_MASTERKEY_FILE_HEX, "r");
+ if(pT==NULL){
+ PanicAlert("could not open " WII_MASTERKEY_FILE_HEX );
+ return NULL;
+ }
+
+ static char hexkey[32];
+ if(fread(hexkey,1,32,pT)<32)
+ {
+ PanicAlert(WII_MASTERKEY_FILE_HEX " is not the right size" );
+ fclose(pT);
+ return NULL;
+ }
+ fclose(pT);
+
+ static char binkey[16];
+ char *t=hexkey;
+ for(int i=0;i<16;i++)
+ {
+ char h[3]={*(t++),*(t++),0};
+ binkey[i] = strtol(h,NULL,16);
+ }
+
+ pT = fopen(WII_MASTERKEY_FILE, "wb");
+ if(pT==NULL){
+ PanicAlert("could not open/make '" WII_MASTERKEY_FILE "' for writing!");
+ return NULL;
+ }
+
+ fwrite(binkey,16,1,pT);
+ fclose(pT);
+
+ pT = fopen(WII_MASTERKEY_FILE, "rb");
+ if(pT==NULL){
+ PanicAlert("could not open '" WII_MASTERKEY_FILE "' for reading!\n did the file get deleted or locked after converting?");
+ return NULL;
+ }
+ }
+ else
+ return NULL;
+ }
+
+ fread(g_MasterKey, 16, 1, pT);
+ fclose(pT);
+ const u32 keyhash = 0x4bc30936;
+ u32 hash = HashAdler32(g_MasterKey, 16);
+ if (hash != keyhash)
+ PanicAlert("Your Wii disc decryption key is bad.", keyhash, hash);
+ else
+ g_MasterKeyInit = true;
+ }
+
+ CBlobBigEndianReader Reader(_rReader);
+
+ u32 numPartitions = Reader.Read32(0x40000);
+ u64 PartitionsOffset = (u64)Reader.Read32(0x40004) << 2;
+ #ifdef _WIN32
+ struct SPartition
+ {
+ u64 Offset;
+ u32 Type;
+ };
+ #endif
+ std::vector<SPartition> PartitionsVec;
+
+ // read all partitions
+ for (u32 i = 0; i < numPartitions; i++)
+ {
+ SPartition Partition;
+ Partition.Offset = ((u64)Reader.Read32(PartitionsOffset + (i * 8) + 0)) << 2;
+ Partition.Type = Reader.Read32(PartitionsOffset + (i * 8) + 4);
+ PartitionsVec.push_back(Partition);
+ }
+
+ // find the partition with the game... type == 1 is prolly the firmware update partition
+ for (size_t i = 0; i < PartitionsVec.size(); i++)
+ {
+ const SPartition& rPartition = PartitionsVec[i];
+
+ if (rPartition.Type == _VolumeType)
+ {
+ u8 SubKey[16];
+ _rReader.Read(rPartition.Offset + 0x1bf, 16, SubKey);
+
+ u8 IV[16];
+ memset(IV, 0, 16);
+ _rReader.Read(rPartition.Offset + 0x44c, 8, IV);
+
+ AES_KEY AES_KEY;
+ AES_set_decrypt_key(g_MasterKey, 128, &AES_KEY);
+
+ u8 VolumeKey[16];
+ AES_cbc_encrypt(SubKey, VolumeKey, 16, &AES_KEY, IV, AES_DECRYPT);
+
+ return new CVolumeWiiCrypted(&_rReader, rPartition.Offset + 0x20000, VolumeKey);
+ }
+ }
+
+ return NULL;
+}
+
+EDiscType GetDiscType(IBlobReader& _rReader)
+{
+ CBlobBigEndianReader Reader(_rReader);
+
+ // check for wii
+ {
+ u32 MagicWord = Reader.Read32(0x18);
+
+ if (MagicWord == 0x5D1C9EA3)
+ {
+ if (Reader.Read32(0x60) != 0)
+ return(DISC_TYPE_WII);
+ else
+ return(DISC_TYPE_WII_CONTAINER);
+ }
+ }
+
+ // check for GC
+ {
+ u32 MagicWord = Reader.Read32(0x1C);
+
+ if (MagicWord == 0xC2339F3D)
+ return(DISC_TYPE_GC);
+ }
+
+ return DISC_TYPE_UNK;
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
index 0b9396fa61..ff7f883636 100644
--- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
@@ -1,466 +1,466 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-#include "stdafx.h"
-
-#include "VolumeDirectory.h"
-#include "FileBlob.h"
-
-namespace DiscIO
-{
-
-static const u8 ENTRY_SIZE = 0x0c;
-static const u8 FILE_ENTRY = 0;
-static const u8 DIRECTORY_ENTRY = 1;
-static const u64 FST_ADDRESS = 0x440;
-static const u32 MAX_NAME_LENGTH = 0x3df;
-
-CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii)
- : m_totalNameSize(0)
- , m_dataStartAddress(-1)
- , m_fstSize(0)
- , m_FSTData(NULL)
-{
- m_rootDirectory = ExtractDirectoryName(_rDirectory);
-
- // create the default disk header
- m_diskHeader = new u8[FST_ADDRESS];
- memset(m_diskHeader, 0, (size_t)FST_ADDRESS);
- SetUniqueID("RZDE01");
- SetName("Default name");
-
- if(_bIsWii)
- {
- SetDiskTypeWii();
- }
- else
- {
- SetDiskTypeGC();
- }
-
- BuildFST();
-}
-
-CVolumeDirectory::~CVolumeDirectory()
-{
- delete m_FSTData;
- m_FSTData = NULL;
-
- delete m_diskHeader;
- m_diskHeader = NULL;
-}
-
-bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory)
-{
- std::string directoryName = ExtractDirectoryName(_rDirectory);
- return File::IsDirectory(directoryName.c_str());
-}
-
-bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
-{
- if(_Offset < FST_ADDRESS)
- {
- WriteToBuffer(0, FST_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer);
- }
-
- if(_Offset < m_dataStartAddress)
- {
- WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer);
- }
-
- if(m_virtualDisk.size() == 0)
- return true;
-
- // Determine which file the offset refers to
- std::map<u64, std::string>::const_iterator fileIter = m_virtualDisk.lower_bound(_Offset);
- if(fileIter->first > _Offset && fileIter != m_virtualDisk.begin())
- --fileIter;
-
- // zero fill to start of file data
- PadToAddress(fileIter->first, _Offset, _Length, _pBuffer);
-
- while(fileIter != m_virtualDisk.end() && _Length > 0)
- {
- _dbg_assert_(DVDINTERFACE, fileIter->first <= _Offset);
- u64 fileOffset = _Offset - fileIter->first;
-
- PlainFileReader* reader = PlainFileReader::Create(fileIter->second.c_str());
- if(reader == NULL)
- return false;
-
- u64 fileSize = reader->GetDataSize();
-
- if(fileOffset < fileSize)
- {
- u64 fileBytes = fileSize - fileOffset;
- if(_Length < fileBytes)
- fileBytes = _Length;
-
- if(!reader->Read(fileOffset, fileBytes, _pBuffer))
- return false;
-
- _Length -= fileBytes;
- _pBuffer += fileBytes;
- _Offset += fileBytes;
- }
-
- ++fileIter;
-
- if(fileIter != m_virtualDisk.end())
- {
- _dbg_assert_(DVDINTERFACE, fileIter->first >= _Offset);
- PadToAddress(fileIter->first, _Offset, _Length, _pBuffer);
- }
- }
-
- return true;
-}
-
-std::string CVolumeDirectory::GetUniqueID() const
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- char buffer[7];
- memcpy(buffer, m_diskHeader, 6);
- buffer[6] = 0;
-
- std::string id = buffer;
- return id;
-}
-
-void CVolumeDirectory::SetUniqueID(std::string _ID)
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- u32 length = _ID.length();
- if(length > 6)
- length = 6;
-
- memcpy(m_diskHeader, _ID.c_str(), length);
-}
-
-IVolume::ECountry CVolumeDirectory::GetCountry() const
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- u8 CountryCode = m_diskHeader[3];
-
- ECountry country = COUNTRY_UNKNOWN;
-
- switch (CountryCode)
- {
- case 'S':
- country = COUNTRY_EUROPE;
- break; // PAL <- that is shitty :) zelda demo disc
-
- case 'P':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'D':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'F':
- country = COUNTRY_FRANCE;
- break; // PAL
-
- case 'X':
- country = COUNTRY_EUROPE;
- break; // XIII <- uses X but is PAL rip
-
- case 'E':
- country = COUNTRY_USA;
- break; // USA
-
- case 'J':
- country = COUNTRY_JAP;
- break; // JAP
-
- case 'O':
- country = COUNTRY_UNKNOWN;
- break; // SDK
-
- default:
- country = COUNTRY_UNKNOWN;
- break;
- }
-
- return(country);
-}
-
-std::string CVolumeDirectory::GetMakerID() const
-{
- return "VOID";
-}
-
-std::string CVolumeDirectory::GetName() const
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
- std::string name = (char*)(m_diskHeader + 0x20);
- return name;
-}
-
-void CVolumeDirectory::SetName(std::string _Name)
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- u32 length = _Name.length();
- if(length > MAX_NAME_LENGTH)
- length = MAX_NAME_LENGTH;
-
- memcpy(m_diskHeader + 0x20, _Name.c_str(), length);
- m_diskHeader[length + 0x20] = 0;
-}
-
-u32 CVolumeDirectory::GetFSTSize() const
-{
- return 0;
-}
-
-std::string CVolumeDirectory::GetApploaderDate() const
-{
- return "VOID";
-}
-
-u64 CVolumeDirectory::GetSize() const
-{
- return 0;
-}
-
-static const char DIR_SEPARATOR =
-#ifdef _WIN32
- '\\';
-#else
- '/';
-#endif
-
-std::string CVolumeDirectory::ExtractDirectoryName(const std::string& _rDirectory)
-{
- std::string directoryName = _rDirectory;
-
- size_t lastSep = directoryName.find_last_of(DIR_SEPARATOR);
-
- if(lastSep != directoryName.size() - 1)
- {
- // TODO: This assumes that file names will always have a dot in them
- // and directory names never will; both assumptions are often
- // right but in general wrong.
- size_t extensionStart = directoryName.find_last_of('.');
- if(extensionStart != std::string::npos && extensionStart > lastSep)
- {
- directoryName.resize(lastSep);
- }
- }
- else
- {
- directoryName.resize(lastSep);
- }
-
- return directoryName;
-}
-
-void CVolumeDirectory::SetDiskTypeWii()
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- m_diskHeader[0x18] = 0x5d;
- m_diskHeader[0x19] = 0x1c;
- m_diskHeader[0x1a] = 0x9e;
- m_diskHeader[0x1b] = 0xa3;
- memset(m_diskHeader + 0x1c, 0, 4);
-
- m_addressShift = 2;
-}
-
-void CVolumeDirectory::SetDiskTypeGC()
-{
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
-
- memset(m_diskHeader + 0x18, 0, 4);
- m_diskHeader[0x1c] = 0xc2;
- m_diskHeader[0x1d] = 0x33;
- m_diskHeader[0x1e] = 0x9f;
- m_diskHeader[0x1f] = 0x3d;
-
- m_addressShift = 0;
-}
-
-void CVolumeDirectory::BuildFST()
-{
- if(m_FSTData)
- {
- delete m_FSTData;
- }
-
- File::FSTEntry rootEntry;
-
- // read data from physical disk to rootEntry
- u32 totalEntries = AddDirectoryEntries(m_rootDirectory, rootEntry) + 1;
-
- m_fstNameOffset = totalEntries * ENTRY_SIZE; // offset in FST nameTable
- m_fstSize = m_fstNameOffset + m_totalNameSize;
- m_FSTData = new u8[(u32)m_fstSize];
-
- // 4 byte aligned start of data on disk
- m_dataStartAddress = (FST_ADDRESS + m_fstSize + 3) & ~3;
- u64 curDataAddress = m_dataStartAddress;
-
- u32 fstOffset = 0; // offset within FST data
- u32 nameOffset = 0; // offset within name table
- u32 rootOffset = 0; // offset of root of FST
-
- // write root entry
- WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries);
-
- for(std::vector<File::FSTEntry>::iterator iter = rootEntry.children.begin(); iter != rootEntry.children.end(); ++iter)
- {
- WriteEntry(*iter, fstOffset, nameOffset, curDataAddress, rootOffset);
- }
-
- // overflow check
- _dbg_assert_(DVDINTERFACE, nameOffset == m_fstSize);
-
- // write FST size and location
- _dbg_assert_(DVDINTERFACE, m_diskHeader);
- Write32((u32)(FST_ADDRESS >> m_addressShift), 0x0424, m_diskHeader);
- Write32((u32)m_fstSize, 0x0428, m_diskHeader);
- Write32((u32)m_fstSize, 0x042c, m_diskHeader);
-}
-
-void CVolumeDirectory::WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src,
- u64& _Address, u64& _Length, u8*& _pBuffer) const
-{
- _dbg_assert_(DVDINTERFACE, _Address >= _SrcStartAddress);
-
- u64 srcOffset = _Address - _SrcStartAddress;
-
- if(srcOffset < _SrcLength)
- {
- u64 srcBytes = _SrcLength - srcOffset;
- if(_Length < srcBytes)
- srcBytes = _Length;
-
- memcpy(_pBuffer, _Src + srcOffset, (size_t)srcBytes);
-
- _Length -= srcBytes;
- _pBuffer += srcBytes;
- _Address += srcBytes;
- }
-}
-
-void CVolumeDirectory::PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const
-{
- if(_StartAddress <= _Address)
- return;
-
- u64 padBytes = _StartAddress - _Address;
- if(padBytes > _Length)
- padBytes = _Length;
-
- if(_Length > 0)
- {
- memset(_pBuffer, 0, (size_t)padBytes);
- _Length -= padBytes;
- _pBuffer += padBytes;
- _Address += padBytes;
- }
-}
-
-void CVolumeDirectory::Write32(u32 data, u32 offset, u8* buffer)
-{
- buffer[offset++] = (data >> 24);
- buffer[offset++] = (data >> 16) & 0xff;
- buffer[offset++] = (data >> 8) & 0xff;
- buffer[offset] = (data) & 0xff;
-}
-
-void CVolumeDirectory::WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length)
-{
- m_FSTData[entryOffset++] = type;
-
- m_FSTData[entryOffset++] = (nameOffset >> 16) & 0xff;
- m_FSTData[entryOffset++] = (nameOffset >> 8) & 0xff;
- m_FSTData[entryOffset++] = (nameOffset) & 0xff;
-
- Write32((u32)(dataOffset >> m_addressShift), entryOffset, m_FSTData);
- entryOffset += 4;
-
- Write32((u32)length, entryOffset, m_FSTData);
- entryOffset += 4;
-}
-
-void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name)
-{
- strncpy((char*)(m_FSTData + nameOffset + m_fstNameOffset), name.c_str(), name.length() + 1);
-
- nameOffset += (name.length() + 1);
-}
-
-void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum)
-{
- if(entry.isDirectory)
- {
- u32 myOffset = fstOffset;
- u32 myEntryNum = myOffset / ENTRY_SIZE;
- WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum, myEntryNum + entry.size + 1);
- WriteEntryName(nameOffset, entry.virtualName);
-
- for(std::vector<File::FSTEntry>::const_iterator iter = entry.children.begin(); iter != entry.children.end(); ++iter)
- {
- WriteEntry(*iter, fstOffset, nameOffset, dataOffset, myEntryNum);
- }
- }
- else
- {
- // put entry in FST
- WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
- WriteEntryName(nameOffset, entry.virtualName);
-
- // write entry to virtual disk
- _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
- m_virtualDisk.insert(make_pair(dataOffset, entry.physicalName));
-
- // 4 byte aligned
- dataOffset = (dataOffset + entry.size + 3) & ~3ULL;
- }
-}
-
-static u32 ComputeNameSize(const File::FSTEntry& parentEntry)
-{
- u32 nameSize = 0;
- const std::vector<File::FSTEntry>& children = parentEntry.children;
- for (std::vector<File::FSTEntry>::const_iterator it = children.begin();
- it != children.end(); ++it)
- {
- const File::FSTEntry& entry = *it;
- if (entry.isDirectory)
- {
- nameSize += ComputeNameSize(entry);
- }
- nameSize += entry.virtualName.length() + 1;
- }
- return nameSize;
-}
-
-u32 CVolumeDirectory::AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry)
-{
- u32 foundEntries = ScanDirectoryTree(_Directory, parentEntry);
- m_totalNameSize += ComputeNameSize(parentEntry);
- return foundEntries;
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+#include "stdafx.h"
+
+#include "VolumeDirectory.h"
+#include "FileBlob.h"
+
+namespace DiscIO
+{
+
+static const u8 ENTRY_SIZE = 0x0c;
+static const u8 FILE_ENTRY = 0;
+static const u8 DIRECTORY_ENTRY = 1;
+static const u64 FST_ADDRESS = 0x440;
+static const u32 MAX_NAME_LENGTH = 0x3df;
+
+CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii)
+ : m_totalNameSize(0)
+ , m_dataStartAddress(-1)
+ , m_fstSize(0)
+ , m_FSTData(NULL)
+{
+ m_rootDirectory = ExtractDirectoryName(_rDirectory);
+
+ // create the default disk header
+ m_diskHeader = new u8[FST_ADDRESS];
+ memset(m_diskHeader, 0, (size_t)FST_ADDRESS);
+ SetUniqueID("RZDE01");
+ SetName("Default name");
+
+ if(_bIsWii)
+ {
+ SetDiskTypeWii();
+ }
+ else
+ {
+ SetDiskTypeGC();
+ }
+
+ BuildFST();
+}
+
+CVolumeDirectory::~CVolumeDirectory()
+{
+ delete m_FSTData;
+ m_FSTData = NULL;
+
+ delete m_diskHeader;
+ m_diskHeader = NULL;
+}
+
+bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory)
+{
+ std::string directoryName = ExtractDirectoryName(_rDirectory);
+ return File::IsDirectory(directoryName.c_str());
+}
+
+bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
+{
+ if(_Offset < FST_ADDRESS)
+ {
+ WriteToBuffer(0, FST_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer);
+ }
+
+ if(_Offset < m_dataStartAddress)
+ {
+ WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer);
+ }
+
+ if(m_virtualDisk.size() == 0)
+ return true;
+
+ // Determine which file the offset refers to
+ std::map<u64, std::string>::const_iterator fileIter = m_virtualDisk.lower_bound(_Offset);
+ if(fileIter->first > _Offset && fileIter != m_virtualDisk.begin())
+ --fileIter;
+
+ // zero fill to start of file data
+ PadToAddress(fileIter->first, _Offset, _Length, _pBuffer);
+
+ while(fileIter != m_virtualDisk.end() && _Length > 0)
+ {
+ _dbg_assert_(DVDINTERFACE, fileIter->first <= _Offset);
+ u64 fileOffset = _Offset - fileIter->first;
+
+ PlainFileReader* reader = PlainFileReader::Create(fileIter->second.c_str());
+ if(reader == NULL)
+ return false;
+
+ u64 fileSize = reader->GetDataSize();
+
+ if(fileOffset < fileSize)
+ {
+ u64 fileBytes = fileSize - fileOffset;
+ if(_Length < fileBytes)
+ fileBytes = _Length;
+
+ if(!reader->Read(fileOffset, fileBytes, _pBuffer))
+ return false;
+
+ _Length -= fileBytes;
+ _pBuffer += fileBytes;
+ _Offset += fileBytes;
+ }
+
+ ++fileIter;
+
+ if(fileIter != m_virtualDisk.end())
+ {
+ _dbg_assert_(DVDINTERFACE, fileIter->first >= _Offset);
+ PadToAddress(fileIter->first, _Offset, _Length, _pBuffer);
+ }
+ }
+
+ return true;
+}
+
+std::string CVolumeDirectory::GetUniqueID() const
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ char buffer[7];
+ memcpy(buffer, m_diskHeader, 6);
+ buffer[6] = 0;
+
+ std::string id = buffer;
+ return id;
+}
+
+void CVolumeDirectory::SetUniqueID(std::string _ID)
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ u32 length = _ID.length();
+ if(length > 6)
+ length = 6;
+
+ memcpy(m_diskHeader, _ID.c_str(), length);
+}
+
+IVolume::ECountry CVolumeDirectory::GetCountry() const
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ u8 CountryCode = m_diskHeader[3];
+
+ ECountry country = COUNTRY_UNKNOWN;
+
+ switch (CountryCode)
+ {
+ case 'S':
+ country = COUNTRY_EUROPE;
+ break; // PAL <- that is shitty :) zelda demo disc
+
+ case 'P':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'D':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'F':
+ country = COUNTRY_FRANCE;
+ break; // PAL
+
+ case 'X':
+ country = COUNTRY_EUROPE;
+ break; // XIII <- uses X but is PAL rip
+
+ case 'E':
+ country = COUNTRY_USA;
+ break; // USA
+
+ case 'J':
+ country = COUNTRY_JAP;
+ break; // JAP
+
+ case 'O':
+ country = COUNTRY_UNKNOWN;
+ break; // SDK
+
+ default:
+ country = COUNTRY_UNKNOWN;
+ break;
+ }
+
+ return(country);
+}
+
+std::string CVolumeDirectory::GetMakerID() const
+{
+ return "VOID";
+}
+
+std::string CVolumeDirectory::GetName() const
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+ std::string name = (char*)(m_diskHeader + 0x20);
+ return name;
+}
+
+void CVolumeDirectory::SetName(std::string _Name)
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ u32 length = _Name.length();
+ if(length > MAX_NAME_LENGTH)
+ length = MAX_NAME_LENGTH;
+
+ memcpy(m_diskHeader + 0x20, _Name.c_str(), length);
+ m_diskHeader[length + 0x20] = 0;
+}
+
+u32 CVolumeDirectory::GetFSTSize() const
+{
+ return 0;
+}
+
+std::string CVolumeDirectory::GetApploaderDate() const
+{
+ return "VOID";
+}
+
+u64 CVolumeDirectory::GetSize() const
+{
+ return 0;
+}
+
+static const char DIR_SEPARATOR =
+#ifdef _WIN32
+ '\\';
+#else
+ '/';
+#endif
+
+std::string CVolumeDirectory::ExtractDirectoryName(const std::string& _rDirectory)
+{
+ std::string directoryName = _rDirectory;
+
+ size_t lastSep = directoryName.find_last_of(DIR_SEPARATOR);
+
+ if(lastSep != directoryName.size() - 1)
+ {
+ // TODO: This assumes that file names will always have a dot in them
+ // and directory names never will; both assumptions are often
+ // right but in general wrong.
+ size_t extensionStart = directoryName.find_last_of('.');
+ if(extensionStart != std::string::npos && extensionStart > lastSep)
+ {
+ directoryName.resize(lastSep);
+ }
+ }
+ else
+ {
+ directoryName.resize(lastSep);
+ }
+
+ return directoryName;
+}
+
+void CVolumeDirectory::SetDiskTypeWii()
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ m_diskHeader[0x18] = 0x5d;
+ m_diskHeader[0x19] = 0x1c;
+ m_diskHeader[0x1a] = 0x9e;
+ m_diskHeader[0x1b] = 0xa3;
+ memset(m_diskHeader + 0x1c, 0, 4);
+
+ m_addressShift = 2;
+}
+
+void CVolumeDirectory::SetDiskTypeGC()
+{
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+
+ memset(m_diskHeader + 0x18, 0, 4);
+ m_diskHeader[0x1c] = 0xc2;
+ m_diskHeader[0x1d] = 0x33;
+ m_diskHeader[0x1e] = 0x9f;
+ m_diskHeader[0x1f] = 0x3d;
+
+ m_addressShift = 0;
+}
+
+void CVolumeDirectory::BuildFST()
+{
+ if(m_FSTData)
+ {
+ delete m_FSTData;
+ }
+
+ File::FSTEntry rootEntry;
+
+ // read data from physical disk to rootEntry
+ u32 totalEntries = AddDirectoryEntries(m_rootDirectory, rootEntry) + 1;
+
+ m_fstNameOffset = totalEntries * ENTRY_SIZE; // offset in FST nameTable
+ m_fstSize = m_fstNameOffset + m_totalNameSize;
+ m_FSTData = new u8[(u32)m_fstSize];
+
+ // 4 byte aligned start of data on disk
+ m_dataStartAddress = (FST_ADDRESS + m_fstSize + 3) & ~3;
+ u64 curDataAddress = m_dataStartAddress;
+
+ u32 fstOffset = 0; // offset within FST data
+ u32 nameOffset = 0; // offset within name table
+ u32 rootOffset = 0; // offset of root of FST
+
+ // write root entry
+ WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries);
+
+ for(std::vector<File::FSTEntry>::iterator iter = rootEntry.children.begin(); iter != rootEntry.children.end(); ++iter)
+ {
+ WriteEntry(*iter, fstOffset, nameOffset, curDataAddress, rootOffset);
+ }
+
+ // overflow check
+ _dbg_assert_(DVDINTERFACE, nameOffset == m_fstSize);
+
+ // write FST size and location
+ _dbg_assert_(DVDINTERFACE, m_diskHeader);
+ Write32((u32)(FST_ADDRESS >> m_addressShift), 0x0424, m_diskHeader);
+ Write32((u32)m_fstSize, 0x0428, m_diskHeader);
+ Write32((u32)m_fstSize, 0x042c, m_diskHeader);
+}
+
+void CVolumeDirectory::WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src,
+ u64& _Address, u64& _Length, u8*& _pBuffer) const
+{
+ _dbg_assert_(DVDINTERFACE, _Address >= _SrcStartAddress);
+
+ u64 srcOffset = _Address - _SrcStartAddress;
+
+ if(srcOffset < _SrcLength)
+ {
+ u64 srcBytes = _SrcLength - srcOffset;
+ if(_Length < srcBytes)
+ srcBytes = _Length;
+
+ memcpy(_pBuffer, _Src + srcOffset, (size_t)srcBytes);
+
+ _Length -= srcBytes;
+ _pBuffer += srcBytes;
+ _Address += srcBytes;
+ }
+}
+
+void CVolumeDirectory::PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const
+{
+ if(_StartAddress <= _Address)
+ return;
+
+ u64 padBytes = _StartAddress - _Address;
+ if(padBytes > _Length)
+ padBytes = _Length;
+
+ if(_Length > 0)
+ {
+ memset(_pBuffer, 0, (size_t)padBytes);
+ _Length -= padBytes;
+ _pBuffer += padBytes;
+ _Address += padBytes;
+ }
+}
+
+void CVolumeDirectory::Write32(u32 data, u32 offset, u8* buffer)
+{
+ buffer[offset++] = (data >> 24);
+ buffer[offset++] = (data >> 16) & 0xff;
+ buffer[offset++] = (data >> 8) & 0xff;
+ buffer[offset] = (data) & 0xff;
+}
+
+void CVolumeDirectory::WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length)
+{
+ m_FSTData[entryOffset++] = type;
+
+ m_FSTData[entryOffset++] = (nameOffset >> 16) & 0xff;
+ m_FSTData[entryOffset++] = (nameOffset >> 8) & 0xff;
+ m_FSTData[entryOffset++] = (nameOffset) & 0xff;
+
+ Write32((u32)(dataOffset >> m_addressShift), entryOffset, m_FSTData);
+ entryOffset += 4;
+
+ Write32((u32)length, entryOffset, m_FSTData);
+ entryOffset += 4;
+}
+
+void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name)
+{
+ strncpy((char*)(m_FSTData + nameOffset + m_fstNameOffset), name.c_str(), name.length() + 1);
+
+ nameOffset += (name.length() + 1);
+}
+
+void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum)
+{
+ if(entry.isDirectory)
+ {
+ u32 myOffset = fstOffset;
+ u32 myEntryNum = myOffset / ENTRY_SIZE;
+ WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum, myEntryNum + entry.size + 1);
+ WriteEntryName(nameOffset, entry.virtualName);
+
+ for(std::vector<File::FSTEntry>::const_iterator iter = entry.children.begin(); iter != entry.children.end(); ++iter)
+ {
+ WriteEntry(*iter, fstOffset, nameOffset, dataOffset, myEntryNum);
+ }
+ }
+ else
+ {
+ // put entry in FST
+ WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size);
+ WriteEntryName(nameOffset, entry.virtualName);
+
+ // write entry to virtual disk
+ _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end());
+ m_virtualDisk.insert(make_pair(dataOffset, entry.physicalName));
+
+ // 4 byte aligned
+ dataOffset = (dataOffset + entry.size + 3) & ~3ULL;
+ }
+}
+
+static u32 ComputeNameSize(const File::FSTEntry& parentEntry)
+{
+ u32 nameSize = 0;
+ const std::vector<File::FSTEntry>& children = parentEntry.children;
+ for (std::vector<File::FSTEntry>::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ const File::FSTEntry& entry = *it;
+ if (entry.isDirectory)
+ {
+ nameSize += ComputeNameSize(entry);
+ }
+ nameSize += entry.virtualName.length() + 1;
+ }
+ return nameSize;
+}
+
+u32 CVolumeDirectory::AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry)
+{
+ u32 foundEntries = ScanDirectoryTree(_Directory, parentEntry);
+ m_totalNameSize += ComputeNameSize(parentEntry);
+ return foundEntries;
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp
index b10319c7cb..638355a943 100644
--- a/Source/Core/DiscIO/Src/VolumeGC.cpp
+++ b/Source/Core/DiscIO/Src/VolumeGC.cpp
@@ -1,169 +1,169 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include "VolumeGC.h"
-#include "StringUtil.h"
-
-namespace DiscIO
-{
-CVolumeGC::CVolumeGC(IBlobReader* _pReader)
- : m_pReader(_pReader)
-{}
-
-CVolumeGC::~CVolumeGC()
-{
- delete m_pReader;
-}
-
-bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
-{
- if (m_pReader == NULL)
- return false;
- return m_pReader->Read(_Offset, _Length, _pBuffer);
-}
-
-std::string CVolumeGC::GetUniqueID() const
-{
- static const std::string NO_UID("NO_UID");
- if (m_pReader == NULL)
- return NO_UID;
-
- char id[6];
- if (!Read(0, sizeof(id), reinterpret_cast<u8*>(id)))
- {
- PanicAlert("Failed to read unique ID from disc image");
- return NO_UID;
- }
-
- return std::string(id, sizeof(id));
-}
-
-IVolume::ECountry CVolumeGC::GetCountry() const
-{
- if (!m_pReader)
- return COUNTRY_UNKNOWN;
-
- u8 CountryCode;
- m_pReader->Read(3, 1, &CountryCode);
-
- ECountry country = COUNTRY_UNKNOWN;
-
- switch (CountryCode)
- {
- case 'S':
- country = COUNTRY_EUROPE;
- break; // PAL // <- that is shitty :) zelda demo disc
-
- case 'P':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'D':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'F':
- country = COUNTRY_FRANCE;
- break; // PAL
-
- case 'X':
- country = COUNTRY_EUROPE;
- break; // XIII <- uses X but is PAL
-
- case 'E':
- country = COUNTRY_USA;
- break; // USA
-
- case 'J':
- country = COUNTRY_JAP;
- break; // JAP
-
- case 'O':
- country = COUNTRY_UNKNOWN;
- break; // SDK
-
- default:
- // PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
- country = COUNTRY_UNKNOWN;
- break;
- }
-
- return(country);
-}
-
-std::string CVolumeGC::GetMakerID() const
-{
- if (m_pReader == NULL)
- return false;
-
- char makerID[3];
- if (!Read(0x4, 0x2, (u8*)&makerID))
- return false;
- makerID[2] = 0;
-
- return makerID;
-}
-
-std::string CVolumeGC::GetName() const
-{
- if (m_pReader == NULL)
- return false;
-
- char name[128];
- if (!Read(0x20, 0x60, (u8*)&name))
- return false;
-
- return name;
-}
-
-u32 CVolumeGC::GetFSTSize() const
-{
- if (m_pReader == NULL)
- return false;
-
- u32 size;
- if (!Read(0x428, 0x4, (u8*)&size))
- return false;
-
- return Common::swap32(size);
-}
-
-std::string CVolumeGC::GetApploaderDate() const
-{
- if (m_pReader == NULL)
- return false;
-
- char date[16];
- if (!Read(0x2440, 0x10, (u8*)&date))
- return false;
- // Should be 0 already, but just in case
- date[10] = 0;
-
- return date;
-}
-
-u64 CVolumeGC::GetSize() const
-{
- if (m_pReader)
- return (size_t)m_pReader->GetDataSize();
- else
- return 0;
-}
-
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include "VolumeGC.h"
+#include "StringUtil.h"
+
+namespace DiscIO
+{
+CVolumeGC::CVolumeGC(IBlobReader* _pReader)
+ : m_pReader(_pReader)
+{}
+
+CVolumeGC::~CVolumeGC()
+{
+ delete m_pReader;
+}
+
+bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
+{
+ if (m_pReader == NULL)
+ return false;
+ return m_pReader->Read(_Offset, _Length, _pBuffer);
+}
+
+std::string CVolumeGC::GetUniqueID() const
+{
+ static const std::string NO_UID("NO_UID");
+ if (m_pReader == NULL)
+ return NO_UID;
+
+ char id[6];
+ if (!Read(0, sizeof(id), reinterpret_cast<u8*>(id)))
+ {
+ PanicAlert("Failed to read unique ID from disc image");
+ return NO_UID;
+ }
+
+ return std::string(id, sizeof(id));
+}
+
+IVolume::ECountry CVolumeGC::GetCountry() const
+{
+ if (!m_pReader)
+ return COUNTRY_UNKNOWN;
+
+ u8 CountryCode;
+ m_pReader->Read(3, 1, &CountryCode);
+
+ ECountry country = COUNTRY_UNKNOWN;
+
+ switch (CountryCode)
+ {
+ case 'S':
+ country = COUNTRY_EUROPE;
+ break; // PAL // <- that is shitty :) zelda demo disc
+
+ case 'P':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'D':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'F':
+ country = COUNTRY_FRANCE;
+ break; // PAL
+
+ case 'X':
+ country = COUNTRY_EUROPE;
+ break; // XIII <- uses X but is PAL
+
+ case 'E':
+ country = COUNTRY_USA;
+ break; // USA
+
+ case 'J':
+ country = COUNTRY_JAP;
+ break; // JAP
+
+ case 'O':
+ country = COUNTRY_UNKNOWN;
+ break; // SDK
+
+ default:
+ // PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
+ country = COUNTRY_UNKNOWN;
+ break;
+ }
+
+ return(country);
+}
+
+std::string CVolumeGC::GetMakerID() const
+{
+ if (m_pReader == NULL)
+ return false;
+
+ char makerID[3];
+ if (!Read(0x4, 0x2, (u8*)&makerID))
+ return false;
+ makerID[2] = 0;
+
+ return makerID;
+}
+
+std::string CVolumeGC::GetName() const
+{
+ if (m_pReader == NULL)
+ return false;
+
+ char name[128];
+ if (!Read(0x20, 0x60, (u8*)&name))
+ return false;
+
+ return name;
+}
+
+u32 CVolumeGC::GetFSTSize() const
+{
+ if (m_pReader == NULL)
+ return false;
+
+ u32 size;
+ if (!Read(0x428, 0x4, (u8*)&size))
+ return false;
+
+ return Common::swap32(size);
+}
+
+std::string CVolumeGC::GetApploaderDate() const
+{
+ if (m_pReader == NULL)
+ return false;
+
+ char date[16];
+ if (!Read(0x2440, 0x10, (u8*)&date))
+ return false;
+ // Should be 0 already, but just in case
+ date[10] = 0;
+
+ return date;
+}
+
+u64 CVolumeGC::GetSize() const
+{
+ if (m_pReader)
+ return (size_t)m_pReader->GetDataSize();
+ else
+ return 0;
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
index 549664f9b0..d5e744bed2 100644
--- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
+++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
@@ -1,254 +1,254 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-#include "VolumeWiiCrypted.h"
-#include "StringUtil.h"
-
-namespace DiscIO
-{
-CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey)
- : m_pReader(_pReader),
- m_pBuffer(0),
- m_VolumeOffset(_VolumeOffset),
- m_LastDecryptedBlockOffset(-1)
-{
- AES_set_decrypt_key(_pVolumeKey, 128, &m_AES_KEY);
- m_pBuffer = new u8[0x8000];
-}
-
-
-CVolumeWiiCrypted::~CVolumeWiiCrypted()
-{
- delete m_pReader; // is this really our responsibility?
- m_pReader = NULL;
- delete[] m_pBuffer;
- m_pBuffer = NULL;
-}
-
-
-bool
-CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- while (_Length > 0)
- {
- static unsigned char IV[16];
-
- // math block offset
- u64 Block = _ReadOffset / 0x7C00;
- u64 Offset = _ReadOffset % 0x7C00;
-
- // read current block
- if (!m_pReader->Read(m_VolumeOffset + Block * 0x8000, 0x8000, m_pBuffer))
- {
- return(false);
- }
-
- if (m_LastDecryptedBlockOffset != Block)
- {
- memcpy(IV, m_pBuffer + 0x3d0, 16);
- AES_cbc_encrypt(m_pBuffer + 0x400, m_LastDecryptedBlock, 0x7C00, &m_AES_KEY, IV, AES_DECRYPT);
-
- m_LastDecryptedBlockOffset = Block;
- }
-
- // copy the encrypted data
- u64 MaxSizeToCopy = 0x7C00 - Offset;
- u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length;
- memcpy(_pBuffer, &m_LastDecryptedBlock[Offset], (size_t)CopySize);
-
- // increase buffers
- _Length -= CopySize;
- _pBuffer += CopySize;
- _ReadOffset += CopySize;
- }
-
- return(true);
-}
-
-std::string
-CVolumeWiiCrypted::GetUniqueID() const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- char ID[7];
-
- if (!Read(0, 6, (u8*)ID))
- {
- return(false);
- }
-
- ID[6] = 0;
-
- return(ID);
-}
-
-
-IVolume::ECountry
-CVolumeWiiCrypted::GetCountry() const
-{
- if (!m_pReader)
- {
- return(COUNTRY_UNKNOWN);
- }
-
- u8 CountryCode;
- m_pReader->Read(3, 1, &CountryCode);
-
- ECountry country = COUNTRY_UNKNOWN;
-
- switch (CountryCode)
- {
- case 'S':
- country = COUNTRY_EUROPE;
- break; // PAL // <- that is shitty :) zelda demo disc
-
- case 'P':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'D':
- country = COUNTRY_EUROPE;
- break; // PAL
-
- case 'F':
- country = COUNTRY_FRANCE;
- break; // PAL
-
- case 'X':
- country = COUNTRY_EUROPE;
- break; // XIII <- uses X but is PAL rip
-
- case 'E':
- country = COUNTRY_USA;
- break; // USA
-
- case 'J':
- country = COUNTRY_JAP;
- break; // JAP
-
- case 'O':
- country = COUNTRY_UNKNOWN;
- break; // SDK
-
- default:
- PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
- break;
- }
-
- return(country);
-}
-
-std::string
-CVolumeWiiCrypted::GetMakerID() const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- char makerID[3];
-
- if (!Read(0x4, 0x2, (u8*)&makerID))
- {
- return(false);
- }
-
- makerID[2] = 0;
-
- return(makerID);
-}
-
-std::string
-CVolumeWiiCrypted::GetName() const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- char name[0xFF];
-
- if (!Read(0x20, 0x60, (u8*)&name))
- {
- return(false);
- }
-
- return(name);
-}
-
-u32
-CVolumeWiiCrypted::GetFSTSize() const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- u32 size;
-
- if (!Read(0x428, 0x4, (u8*)&size))
- {
- return(false);
- }
-
- return(size);
-}
-
-std::string
-CVolumeWiiCrypted::GetApploaderDate() const
-{
- if (m_pReader == NULL)
- {
- return(false);
- }
-
- char date[16];
-
- if (!Read(0x2440, 0x10, (u8*)&date))
- {
- return(false);
- }
-
- date[10] = 0;
-
- return(date);
-}
-
-
-u64
-CVolumeWiiCrypted::GetSize() const
-{
- if (m_pReader)
- {
- return(m_pReader->GetDataSize());
- }
- else
- {
- return(0);
- }
-}
-} // namespace
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include "VolumeWiiCrypted.h"
+#include "StringUtil.h"
+
+namespace DiscIO
+{
+CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey)
+ : m_pReader(_pReader),
+ m_pBuffer(0),
+ m_VolumeOffset(_VolumeOffset),
+ m_LastDecryptedBlockOffset(-1)
+{
+ AES_set_decrypt_key(_pVolumeKey, 128, &m_AES_KEY);
+ m_pBuffer = new u8[0x8000];
+}
+
+
+CVolumeWiiCrypted::~CVolumeWiiCrypted()
+{
+ delete m_pReader; // is this really our responsibility?
+ m_pReader = NULL;
+ delete[] m_pBuffer;
+ m_pBuffer = NULL;
+}
+
+
+bool
+CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ while (_Length > 0)
+ {
+ static unsigned char IV[16];
+
+ // math block offset
+ u64 Block = _ReadOffset / 0x7C00;
+ u64 Offset = _ReadOffset % 0x7C00;
+
+ // read current block
+ if (!m_pReader->Read(m_VolumeOffset + Block * 0x8000, 0x8000, m_pBuffer))
+ {
+ return(false);
+ }
+
+ if (m_LastDecryptedBlockOffset != Block)
+ {
+ memcpy(IV, m_pBuffer + 0x3d0, 16);
+ AES_cbc_encrypt(m_pBuffer + 0x400, m_LastDecryptedBlock, 0x7C00, &m_AES_KEY, IV, AES_DECRYPT);
+
+ m_LastDecryptedBlockOffset = Block;
+ }
+
+ // copy the encrypted data
+ u64 MaxSizeToCopy = 0x7C00 - Offset;
+ u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length;
+ memcpy(_pBuffer, &m_LastDecryptedBlock[Offset], (size_t)CopySize);
+
+ // increase buffers
+ _Length -= CopySize;
+ _pBuffer += CopySize;
+ _ReadOffset += CopySize;
+ }
+
+ return(true);
+}
+
+std::string
+CVolumeWiiCrypted::GetUniqueID() const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ char ID[7];
+
+ if (!Read(0, 6, (u8*)ID))
+ {
+ return(false);
+ }
+
+ ID[6] = 0;
+
+ return(ID);
+}
+
+
+IVolume::ECountry
+CVolumeWiiCrypted::GetCountry() const
+{
+ if (!m_pReader)
+ {
+ return(COUNTRY_UNKNOWN);
+ }
+
+ u8 CountryCode;
+ m_pReader->Read(3, 1, &CountryCode);
+
+ ECountry country = COUNTRY_UNKNOWN;
+
+ switch (CountryCode)
+ {
+ case 'S':
+ country = COUNTRY_EUROPE;
+ break; // PAL // <- that is shitty :) zelda demo disc
+
+ case 'P':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'D':
+ country = COUNTRY_EUROPE;
+ break; // PAL
+
+ case 'F':
+ country = COUNTRY_FRANCE;
+ break; // PAL
+
+ case 'X':
+ country = COUNTRY_EUROPE;
+ break; // XIII <- uses X but is PAL rip
+
+ case 'E':
+ country = COUNTRY_USA;
+ break; // USA
+
+ case 'J':
+ country = COUNTRY_JAP;
+ break; // JAP
+
+ case 'O':
+ country = COUNTRY_UNKNOWN;
+ break; // SDK
+
+ default:
+ PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
+ break;
+ }
+
+ return(country);
+}
+
+std::string
+CVolumeWiiCrypted::GetMakerID() const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ char makerID[3];
+
+ if (!Read(0x4, 0x2, (u8*)&makerID))
+ {
+ return(false);
+ }
+
+ makerID[2] = 0;
+
+ return(makerID);
+}
+
+std::string
+CVolumeWiiCrypted::GetName() const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ char name[0xFF];
+
+ if (!Read(0x20, 0x60, (u8*)&name))
+ {
+ return(false);
+ }
+
+ return(name);
+}
+
+u32
+CVolumeWiiCrypted::GetFSTSize() const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ u32 size;
+
+ if (!Read(0x428, 0x4, (u8*)&size))
+ {
+ return(false);
+ }
+
+ return(size);
+}
+
+std::string
+CVolumeWiiCrypted::GetApploaderDate() const
+{
+ if (m_pReader == NULL)
+ {
+ return(false);
+ }
+
+ char date[16];
+
+ if (!Read(0x2440, 0x10, (u8*)&date))
+ {
+ return(false);
+ }
+
+ date[10] = 0;
+
+ return(date);
+}
+
+
+u64
+CVolumeWiiCrypted::GetSize() const
+{
+ if (m_pReader)
+ {
+ return(m_pReader->GetDataSize());
+ }
+ else
+ {
+ return(0);
+ }
+}
+} // namespace
diff --git a/Source/Core/DiscIO/Src/stdafx.cpp b/Source/Core/DiscIO/Src/stdafx.cpp
index 80a57737ae..903e31a1fc 100644
--- a/Source/Core/DiscIO/Src/stdafx.cpp
+++ b/Source/Core/DiscIO/Src/stdafx.cpp
@@ -1,21 +1,21 @@
-// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file