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)