Merge pull request #10507 from JosJuice/convertcommand-non-gc-wii

DolphinTool: Allow converting non-GC/Wii files
This commit is contained in:
Admiral H. Curtiss 2022-03-23 22:47:41 +01:00 committed by GitHub
commit 1a5a52c00c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 33 deletions

View file

@ -2,10 +2,25 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "DolphinTool/ConvertCommand.h" #include "DolphinTool/ConvertCommand.h"
#include "UICommon/UICommon.h"
#include <iostream>
#include <limits>
#include <optional>
#include <string>
#include <vector>
#include <OptionParser.h> #include <OptionParser.h>
#include "Common/CommonTypes.h"
#include "DiscIO/Blob.h"
#include "DiscIO/DiscUtils.h"
#include "DiscIO/ScrubbedBlob.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeDisc.h"
#include "DiscIO/WIABlob.h"
#include "DolphinTool/Command.h"
#include "UICommon/UICommon.h"
namespace DolphinTool namespace DolphinTool
{ {
int ConvertCommand::Main(const std::vector<std::string>& args) int ConvertCommand::Main(const std::vector<std::string>& args)
@ -99,21 +114,46 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
} }
const DiscIO::BlobType format = format_o.value(); const DiscIO::BlobType format = format_o.value();
// Open the volume now for inspection // Open the blob reader
std::unique_ptr<DiscIO::Volume> volume = DiscIO::CreateVolume(input_file_path); std::unique_ptr<DiscIO::BlobReader> blob_reader = DiscIO::CreateBlobReader(input_file_path);
if (!volume) if (!blob_reader)
{ {
std::cerr << "Error: Unable to open disc image" << std::endl; std::cerr << "Error: The input file could not be opened." << std::endl;
return 1; return 1;
} }
// --scrub // --scrub
const bool scrub = static_cast<bool>(options.get("scrub")); const bool scrub = static_cast<bool>(options.get("scrub"));
if (scrub && volume->IsDatelDisc()) // Open the volume
std::unique_ptr<DiscIO::Volume> volume = DiscIO::CreateDisc(input_file_path);
if (!volume)
{ {
std::cerr << "Error: Scrubbing a Datel disc is not supported"; if (scrub)
return 1; {
std::cerr << "Error: Scrubbing is only supported for GC/Wii disc images." << std::endl;
return 1;
}
std::cerr << "Warning: The input file is not a GC/Wii disc image. Continuing anyway."
<< std::endl;
}
if (scrub)
{
if (volume->IsDatelDisc())
{
std::cerr << "Error: Scrubbing a Datel disc is not supported." << std::endl;
return 1;
}
blob_reader = DiscIO::ScrubbedBlob::Create(input_file_path);
if (!blob_reader)
{
std::cerr << "Error: Unable to process disc image. Try again without --scrub." << std::endl;
return 1;
}
} }
if (scrub && format == DiscIO::BlobType::RVZ) if (scrub && format == DiscIO::BlobType::RVZ)
@ -130,7 +170,7 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
<< std::endl; << std::endl;
} }
if (!scrub && format == DiscIO::BlobType::GCZ && if (!scrub && format == DiscIO::BlobType::GCZ && volume &&
volume->GetVolumeType() == DiscIO::Platform::WiiDisc && !volume->IsDatelDisc()) volume->GetVolumeType() == DiscIO::Platform::WiiDisc && !volume->IsDatelDisc())
{ {
std::cerr << "Warning: Converting Wii disc images to GCZ without scrubbing may not offer space " std::cerr << "Warning: Converting Wii disc images to GCZ without scrubbing may not offer space "
@ -138,7 +178,7 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
<< std::endl; << std::endl;
} }
if (volume->IsNKit()) if (volume && volume->IsNKit())
{ {
std::cerr << "Warning: Converting an NKit file, output will still be NKit! Continuing anyway." std::cerr << "Warning: Converting an NKit file, output will still be NKit! Continuing anyway."
<< std::endl; << std::endl;
@ -171,7 +211,7 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
<< std::endl; << std::endl;
} }
if (format == DiscIO::BlobType::GCZ && if (format == DiscIO::BlobType::GCZ && volume &&
!DiscIO::IsGCZBlockSizeLegacyCompatible(block_size_o.value(), volume->GetSize())) !DiscIO::IsGCZBlockSizeLegacyCompatible(block_size_o.value(), volume->GetSize()))
{ {
std::cerr << "Warning: For GCZs to be compatible with Dolphin < 5.0-11893, " std::cerr << "Warning: For GCZs to be compatible with Dolphin < 5.0-11893, "
@ -230,17 +270,6 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
} }
} }
// Open the blob reader
std::unique_ptr<DiscIO::BlobReader> blob_reader =
scrub ? DiscIO::ScrubbedBlob::Create(input_file_path) :
DiscIO::CreateBlobReader(input_file_path);
if (!blob_reader)
{
std::cerr << "Error: Unable to process disc image. If --scrub is enabled, try again without it."
<< std::endl;
return 1;
}
// Perform the conversion // Perform the conversion
const auto NOOP_STATUS_CALLBACK = [](const std::string& text, float percent) { return true; }; const auto NOOP_STATUS_CALLBACK = [](const std::string& text, float percent) { return true; };
@ -249,28 +278,43 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
switch (format) switch (format)
{ {
case DiscIO::BlobType::PLAIN: case DiscIO::BlobType::PLAIN:
{
success = DiscIO::ConvertToPlain(blob_reader.get(), input_file_path, output_file_path, success = DiscIO::ConvertToPlain(blob_reader.get(), input_file_path, output_file_path,
NOOP_STATUS_CALLBACK); NOOP_STATUS_CALLBACK);
break; break;
}
case DiscIO::BlobType::GCZ: case DiscIO::BlobType::GCZ:
success = DiscIO::ConvertToGCZ(blob_reader.get(), input_file_path, output_file_path, {
volume->GetVolumeType() == DiscIO::Platform::WiiDisc ? 1 : 0, u32 sub_type = std::numeric_limits<u32>::max();
if (volume)
{
if (volume->GetVolumeType() == DiscIO::Platform::GameCubeDisc)
sub_type = 0;
else if (volume->GetVolumeType() == DiscIO::Platform::WiiDisc)
sub_type = 1;
}
success = DiscIO::ConvertToGCZ(blob_reader.get(), input_file_path, output_file_path, sub_type,
block_size_o.value(), NOOP_STATUS_CALLBACK); block_size_o.value(), NOOP_STATUS_CALLBACK);
break; break;
}
case DiscIO::BlobType::WIA: case DiscIO::BlobType::WIA:
case DiscIO::BlobType::RVZ: case DiscIO::BlobType::RVZ:
{
success = DiscIO::ConvertToWIAOrRVZ(blob_reader.get(), input_file_path, output_file_path, success = DiscIO::ConvertToWIAOrRVZ(blob_reader.get(), input_file_path, output_file_path,
format == DiscIO::BlobType::RVZ, compression_o.value(), format == DiscIO::BlobType::RVZ, compression_o.value(),
compression_level_o.value(), block_size_o.value(), compression_level_o.value(), block_size_o.value(),
NOOP_STATUS_CALLBACK); NOOP_STATUS_CALLBACK);
break; break;
}
default: default:
{
ASSERT(false); ASSERT(false);
break; break;
} }
}
if (!success) if (!success)
{ {
@ -282,7 +326,7 @@ int ConvertCommand::Main(const std::vector<std::string>& args)
} }
std::optional<DiscIO::WIARVZCompressionType> std::optional<DiscIO::WIARVZCompressionType>
ConvertCommand::ParseCompressionTypeString(const std::string compression_str) ConvertCommand::ParseCompressionTypeString(const std::string& compression_str)
{ {
if (compression_str == "none") if (compression_str == "none")
return DiscIO::WIARVZCompressionType::None; return DiscIO::WIARVZCompressionType::None;
@ -300,7 +344,7 @@ ConvertCommand::ParseCompressionTypeString(const std::string compression_str)
return std::nullopt; return std::nullopt;
} }
std::optional<DiscIO::BlobType> ConvertCommand::ParseFormatString(const std::string format_str) std::optional<DiscIO::BlobType> ConvertCommand::ParseFormatString(const std::string& format_str)
{ {
if (format_str == "iso") if (format_str == "iso")
return DiscIO::BlobType::PLAIN; return DiscIO::BlobType::PLAIN;

View file

@ -3,14 +3,11 @@
#pragma once #pragma once
#include <cstdint>
#include <optional> #include <optional>
#include <string>
#include <vector>
#include "DiscIO/Blob.h" #include "DiscIO/Blob.h"
#include "DiscIO/DiscUtils.h"
#include "DiscIO/ScrubbedBlob.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeDisc.h"
#include "DiscIO/WIABlob.h" #include "DiscIO/WIABlob.h"
#include "DolphinTool/Command.h" #include "DolphinTool/Command.h"
@ -23,8 +20,8 @@ public:
private: private:
std::optional<DiscIO::WIARVZCompressionType> std::optional<DiscIO::WIARVZCompressionType>
ParseCompressionTypeString(const std::string compression_str); ParseCompressionTypeString(const std::string& compression_str);
std::optional<DiscIO::BlobType> ParseFormatString(const std::string format_str); std::optional<DiscIO::BlobType> ParseFormatString(const std::string& format_str);
}; };
} // namespace DolphinTool } // namespace DolphinTool