diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp
index 7e0216d375..3cf3f04341 100644
--- a/Source/Core/Core/Src/CoreParameter.cpp
+++ b/Source/Core/Core/Src/CoreParameter.cpp
@@ -138,6 +138,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
SplitPath(m_strFilename, NULL, NULL, &Extension);
if (!strcasecmp(Extension.c_str(), ".gcm") ||
!strcasecmp(Extension.c_str(), ".iso") ||
+ !strcasecmp(Extension.c_str(), ".ciso") ||
!strcasecmp(Extension.c_str(), ".gcz") ||
bootDrive)
{
diff --git a/Source/Core/DiscIO/DiscIO.vcproj b/Source/Core/DiscIO/DiscIO.vcproj
index 72864e2af9..6bf57643b5 100644
--- a/Source/Core/DiscIO/DiscIO.vcproj
+++ b/Source/Core/DiscIO/DiscIO.vcproj
@@ -472,6 +472,14 @@
RelativePath=".\Src\Blob.h"
>
+
+
+
+
diff --git a/Source/Core/DiscIO/Src/Blob.cpp b/Source/Core/DiscIO/Src/Blob.cpp
index 46e5d5e4ee..a728780f23 100644
--- a/Source/Core/DiscIO/Src/Blob.cpp
+++ b/Source/Core/DiscIO/Src/Blob.cpp
@@ -21,6 +21,7 @@
#include "Blob.h"
#include "CompressedBlob.h"
#include "FileBlob.h"
+#include "CISOBlob.h"
#include "DriveBlob.h"
namespace DiscIO
@@ -130,6 +131,9 @@ IBlobReader* CreateBlobReader(const char* filename)
if (IsCompressedBlob(filename))
return CompressedBlobReader::Create(filename);
+ if (IsCISOBlob(filename))
+ return CISOFileReader::Create(filename);
+
// Still here? Assume plain file - since we know it exists due to the File::Exists check above.
return PlainFileReader::Create(filename);
}
diff --git a/Source/Core/DiscIO/Src/CISOBlob.cpp b/Source/Core/DiscIO/Src/CISOBlob.cpp
new file mode 100644
index 0000000000..7addf252f5
--- /dev/null
+++ b/Source/Core/DiscIO/Src/CISOBlob.cpp
@@ -0,0 +1,104 @@
+// Copyright (C) 2003 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 "CISOBlob.h"
+
+namespace DiscIO
+{
+
+CISOFileReader::CISOFileReader(FILE* file__)
+{
+ file_ = file__;
+ fseek(file_, 0, SEEK_END);
+ size = ftell(file_);
+ fseek(file_, 0, SEEK_SET);
+
+ memset(&header, 0, sizeof(header));
+ fread(&header, sizeof(header), 1, file_);
+
+ CISO_Map_t count = 0;
+ int idx;
+ for (idx = 0; idx < CISO_MAP_SIZE; idx++)
+ ciso_map[idx] = (header.map[idx] == 1) ? count++ : CISO_UNUSED_BLOCK;
+}
+
+CISOFileReader* CISOFileReader::Create(const char* filename)
+{
+ if (IsCISOBlob(filename))
+ {
+ FILE* file_ = fopen(filename, "rb");
+ return new CISOFileReader(file_);
+ }
+ else
+ return NULL;
+}
+
+CISOFileReader::~CISOFileReader()
+{
+ fclose(file_);
+}
+
+bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
+{
+ u64 bytesRead = 0;
+ while (bytesRead < nbytes)
+ {
+ u32 block = (u32)(offset / header.block_size);
+ u32 data_offset = offset % header.block_size;
+ u32 bytes_to_read = (u32)min((u64)(header.block_size - data_offset), nbytes);
+ if ((block >= CISO_MAP_SIZE) || (ciso_map[block] == CISO_UNUSED_BLOCK))
+ {
+ memset(out_ptr, 0, bytes_to_read);
+ out_ptr += bytes_to_read;
+ offset += bytes_to_read;
+ bytesRead += bytes_to_read;
+ }
+ else
+ {
+ // calcualte the base address
+ u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset;
+
+ if (fseeko(file_, (long)file_off, SEEK_SET) != 0)
+ return false;
+ if (fread(out_ptr, 1, bytes_to_read, file_) != bytes_to_read)
+ return false;
+
+ out_ptr += bytes_to_read;
+ offset += bytes_to_read;
+ bytesRead += bytes_to_read;
+ }
+ }
+ return true;
+}
+
+bool IsCISOBlob(const char* filename)
+{
+ FILE* f = fopen(filename, "rb");
+
+ if (!f)
+ return false;
+
+ CISO_Head_t header;
+ fread(&header, sizeof(header), 1, f);
+ fclose(f);
+ return (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0);
+}
+
+} // namespace
diff --git a/Source/Core/DiscIO/Src/CISOBlob.h b/Source/Core/DiscIO/Src/CISOBlob.h
new file mode 100644
index 0000000000..772c7c47e6
--- /dev/null
+++ b/Source/Core/DiscIO/Src/CISOBlob.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2003 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/
+
+#ifndef _CISO_BLOB_H
+#define _CISO_BLOB_H
+
+#include "Blob.h"
+
+#include
+
+#define CISO_MAGIC "CISO"
+#define CISO_HEAD_SIZE (0x8000)
+#define CISO_MAP_SIZE (CISO_HEAD_SIZE - 8)
+
+namespace DiscIO
+{
+
+bool IsCISOBlob(const char* filename);
+
+// Blocks that won't compress to less than 97% of the original size are stored as-is.
+typedef struct CISO_Head_t
+{
+ u8 magic[4]; // "CISO"
+ u32 block_size; // stored as litte endian (not network byte order)
+ u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid
+} CISO_Head_t;
+
+typedef u16 CISO_Map_t;
+
+const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0;
+
+class CISOFileReader : public IBlobReader
+{
+ FILE* file_;
+ CISOFileReader(FILE* file__);
+ s64 size;
+
+public:
+ static CISOFileReader* Create(const char* filename);
+ ~CISOFileReader();
+ u64 GetDataSize() const { return size; }
+ u64 GetRawSize() const { return size; }
+ bool Read(u64 offset, u64 nbytes, u8* out_ptr);
+
+private:
+ CISO_Head_t header;
+ CISO_Map_t ciso_map[CISO_MAP_SIZE];
+};
+
+} // namespace
+
+#endif // _FILE_BLOB_H
diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp
index 0483ef03f4..433cbeceb8 100644
--- a/Source/Core/DolphinWX/Src/ConfigMain.cpp
+++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp
@@ -688,7 +688,7 @@ void CConfigMain::CreateGUIControls()
wxStaticText* DefaultISOText = new wxStaticText(PathsPage, ID_DEFAULTISO_TEXT, wxT("Default ISO:"), wxDefaultPosition, wxDefaultSize);
DefaultISO = new wxFilePickerCtrl(PathsPage, ID_DEFAULTISO, wxEmptyString, wxT("Choose a default ISO:"),
- wxString::Format(wxT("All GC/Wii images (gcm, iso, gcz)|*.gcm;*.iso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr),
+ wxString::Format(wxT("All GC/Wii images (gcm, iso, ciso, gcz)|*.gcm;*.iso;*.ciso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr),
wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_OPEN);
wxStaticText* DVDRootText = new wxStaticText(PathsPage, ID_DVDROOT_TEXT, wxT("DVD Root:"), wxDefaultPosition, wxDefaultSize);
DVDRoot = new wxDirPickerCtrl(PathsPage, ID_DVDROOT, wxEmptyString, wxT("Choose a DVD root directory:"), wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL);
diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp
index 4e30ecb224..39727442df 100644
--- a/Source/Core/DolphinWX/Src/FrameTools.cpp
+++ b/Source/Core/DolphinWX/Src/FrameTools.cpp
@@ -588,7 +588,7 @@ void CFrame::DoOpen(bool Boot)
wxEmptyString, wxEmptyString, wxEmptyString,
wxString::Format
(
- _T("All GC/Wii files (elf, dol, gcm, iso, wad)|*.elf;*.dol;*.gcm;*.iso;*.gcz;*.wad|All files (%s)|%s"),
+ _T("All GC/Wii files (elf, dol, gcm, iso, ciso, wad)|*.elf;*.dol;*.gcm;*.iso;*.ciso;*.gcz;*.wad|All files (%s)|%s"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp
index 485b7a42de..c699ee954f 100644
--- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp
+++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp
@@ -566,6 +566,7 @@ void CGameListCtrl::ScanForISOs()
if (SConfig::GetInstance().m_ListWii || SConfig::GetInstance().m_ListGC)
{
Extensions.push_back("*.iso");
+ Extensions.push_back("*.ciso");
Extensions.push_back("*.gcz");
}
if (SConfig::GetInstance().m_ListWad)