Skip to content

Commit

Permalink
[libromdata] CisoGcnReader: IDiscReader class for GCN/Wii CISO files.
Browse files Browse the repository at this point in the history
This is a sparse image format supported by Dolphin and a few USB loaders.
Not nearly as common as WBFS, though.

This CISO is also unrelated to the PSP CISO format, which has zlib
compression in addition to sparse.

NOTE: isRomSupported() can't determine the system type, since the disc
header is at $8000, so it sets the system type to unknown while setting
format to CISO. In this case, the GameCube constructor will check the
magic values itself to determine the actual system.

Added file extensions ".ciso" and ".cso".

TODO:
- Write an IDiscReaderFactory class to auto-detect the different types
  of disc image formats and return an IDiscReader.
- Add support for Dolphin GCZ images. (requires zlib)
- Maybe add support for PSP CISO images later, if I ever implement
  support for PSP disc images.
  • Loading branch information
GerbilSoft committed Sep 21, 2016
1 parent f499dd0 commit dc062bf
Show file tree
Hide file tree
Showing 5 changed files with 664 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/libromdata/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ SET(libromdata_SRCS
img/RpImageLoader.cpp
disc/DiscReader.cpp
disc/WbfsReader.cpp
disc/CisoGcnReader.cpp
disc/GcnPartition.cpp
disc/GcnPartitionPrivate.cpp
disc/WiiPartition.cpp
Expand Down Expand Up @@ -118,6 +119,8 @@ SET(libromdata_H
disc/IDiscReader.hpp
disc/DiscReader.hpp
disc/WbfsReader.hpp
disc/CisoGcnReader.hpp
disc/ciso_gcn.h
disc/IPartition.hpp
disc/GcnPartition.hpp
disc/GcnPartitionPrivate.hpp
Expand Down
44 changes: 43 additions & 1 deletion src/libromdata/GameCube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
// DiscReader
#include "disc/DiscReader.hpp"
#include "disc/WbfsReader.hpp"
#include "disc/CisoGcnReader.hpp"
#include "disc/WiiPartition.hpp"

// C includes. (C++ namespace)
Expand Down Expand Up @@ -81,6 +82,7 @@ class GameCubePrivate
// High byte: Image format.
DISC_FORMAT_RAW = (0 << 8), // Raw image. (ISO, GCM)
DISC_FORMAT_WBFS = (1 << 8), // WBFS image. (Wii only)
DISC_FORMAT_CISO = (2 << 8), // CISO image.
DISC_FORMAT_UNKNOWN = (0xFF << 8),
DISC_FORMAT_MASK = (0xFF << 8),
};
Expand Down Expand Up @@ -499,6 +501,9 @@ GameCube::GameCube(IRpFile *file)
case GameCubePrivate::DISC_FORMAT_WBFS:
d->discReader = new WbfsReader(m_file);
break;
case GameCubePrivate::DISC_FORMAT_CISO:
d->discReader = new CisoGcnReader(m_file);
break;
case GameCubePrivate::DISC_FORMAT_UNKNOWN:
default:
d->discType = GameCubePrivate::DISC_UNKNOWN;
Expand All @@ -517,6 +522,33 @@ GameCube::GameCube(IRpFile *file)
d->discReader = nullptr;
d->discType = GameCubePrivate::DISC_UNKNOWN;
m_isValid = false;
return;
}

if (d->discType != GameCubePrivate::DISC_UNKNOWN &&
((d->discType & GameCubePrivate::DISC_SYSTEM_MASK) == GameCubePrivate::DISC_SYSTEM_UNKNOWN))
{
// isRomSupported() was unable to determine the
// system type, possibly due to format limitations.
// Example: CISO doesn't store a copy of the disc header
// in range of the data we read.
if (be32_to_cpu(d->discHeader.magic_wii) == WII_MAGIC) {
// Wii disc image.
d->discType &= ~GameCubePrivate::DISC_SYSTEM_MASK;
d->discType |= GameCubePrivate::DISC_SYSTEM_WII;
} else if (be32_to_cpu(d->discHeader.magic_gcn) == GCN_MAGIC) {
// GameCube disc image.
// TODO: Check for Triforce?
d->discType &= ~GameCubePrivate::DISC_SYSTEM_MASK;
d->discType |= GameCubePrivate::DISC_SYSTEM_GCN;
} else {
// Unknown system type.
delete d->discReader;
d->discReader = nullptr;
d->discType = GameCubePrivate::DISC_UNKNOWN;
m_isValid = false;
return;
}
}
}
}
Expand Down Expand Up @@ -587,6 +619,14 @@ int GameCube::isRomSupported_static(const DetectInfo *info)
}
}

// Check for CISO.
if (CisoGcnReader::isDiscSupported_static(info->pHeader, info->szHeader) >= 0) {
// CISO format doesn't store a copy of the disc header
// at the beginning of the disc, so we can't check the
// system format here.
return GameCubePrivate::DISC_SYSTEM_UNKNOWN | GameCubePrivate::DISC_FORMAT_CISO;
}

// Not supported.
return GameCubePrivate::DISC_UNKNOWN;
}
Expand Down Expand Up @@ -648,10 +688,12 @@ vector<const rp_char*> GameCube::supportedFileExtensions_static(void)
{
// TODO: Add ".iso" later? (Too generic, though...)
vector<const rp_char*> ret;
ret.reserve(3);
ret.reserve(5);
ret.push_back(_RP(".gcm"));
ret.push_back(_RP(".rvm"));
ret.push_back(_RP(".wbfs"));
ret.push_back(_RP(".ciso"));
ret.push_back(_RP(".cso"));
return ret;
}

Expand Down

0 comments on commit dc062bf

Please sign in to comment.