Skip to content

Commit

Permalink
skeleton, sector ISO sectorOffset relative to file, some refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
superg committed Nov 14, 2023
1 parent 8199ca3 commit 8592379
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 9 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ target_sources(redumper
"options.ixx"
"redumper.ixx"
"rom_entry.ixx"
"skeleton.ixx"
"split.ixx"
"version.ixx"
)
Expand Down
4 changes: 2 additions & 2 deletions filesystem/iso9660/iso9660_entry.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public:

uint32_t sectorsOffset() const
{
return _directoryRecord.offset.lsb;
return _directoryRecord.offset.lsb - _sectorReader->sectorsBase();
}


Expand Down Expand Up @@ -170,7 +170,7 @@ public:
{
std::vector<uint8_t> sectors(sectorsSize() * FORM1_DATA_SIZE);

uint32_t sectors_read = _sectorReader->readLBA(sectors.data(), sectorsOffset(), sectorsSize());
uint32_t sectors_read = _sectorReader->read(sectors.data(), sectorsOffset(), sectorsSize());
sectors.resize(sectors_read * FORM1_DATA_SIZE);

return sectors;
Expand Down
2 changes: 2 additions & 0 deletions hash.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export void redumper_hash(Context &ctx, Options &options)
{
files.push_back(image_prefix + ".iso");
}
else
throw_line("image file not found");

if(!files.empty())
{
Expand Down
2 changes: 2 additions & 0 deletions info.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export void redumper_info(Context &ctx, Options &options)
{
tracks.emplace_back(image_prefix + ".iso", TrackType::ISO);
}
else
throw_line("image file not found");

bool separate_nl = false;
for(auto const &t : tracks)
Expand Down
8 changes: 4 additions & 4 deletions readers/image_bin_form1_reader.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ public:
return sectors_read;
}


uint32_t readLBA(uint8_t *sectors, uint32_t lba, uint32_t count) override
uint32_t sectorsBase() override
{
return read(sectors, lba - _baseLBA, count);
};
return _baseLBA;
}


uint32_t sectorsCount() const override
Expand Down
2 changes: 1 addition & 1 deletion readers/sector_reader.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class SectorReader
{
public:
virtual uint32_t read(uint8_t *sectors, uint32_t index, uint32_t count) = 0;
virtual uint32_t readLBA(uint8_t *sectors, uint32_t lba, uint32_t count) { return read(sectors, lba, count); }
virtual uint32_t sectorsBase() { return 0; }
virtual uint32_t sectorSize() const = 0;
virtual uint32_t sectorsCount() const { return std::numeric_limits<uint32_t>::max(); }
};
Expand Down
2 changes: 2 additions & 0 deletions redumper.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import options;
import scsi.cmd;
import scsi.mmc;
import scsi.sptd;
import skeleton;
import utils.file_io;
import utils.logger;
import utils.misc;
Expand Down Expand Up @@ -128,6 +129,7 @@ const std::map<std::string, std::pair<bool, void (*)(Context &, Options &)>> COM
{ "split" , { false, redumper_split }},
{ "hash" , { false, redumper_hash }},
{ "info" , { false, redumper_info }},
{ "skeleton" , { false, redumper_skeleton }},

{ "subchannel", { false, redumper_subchannel }},
{ "debug" , { false, redumper_debug }}
Expand Down
143 changes: 143 additions & 0 deletions skeleton.ixx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
module;

#include <filesystem>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include "throw_line.hh"

export module skeleton;

import cd.cd;
import cd.cdrom;
import dump;
import filesystem.iso9660;
import options;
import readers.sector_reader;
import readers.form1_reader;
import readers.image_bin_form1_reader;
import readers.image_iso_form1_reader;
import utils.logger;
import utils.misc;



namespace gpsxre
{

void skeleton(const std::string &image_prefix, const std::string &image_path, bool iso, Options &options)
{
std::filesystem::path skeleton_path(image_prefix + ".skeleton");
std::filesystem::path index_path(image_prefix + ".index");

if(!options.overwrite && (std::filesystem::exists(skeleton_path) || std::filesystem::exists(index_path)))
throw_line("skeleton/index file already exists");

std::vector<std::pair<uint32_t, uint32_t>> files;

files.emplace_back(0, iso9660::SYSTEM_AREA_SIZE);

std::unique_ptr<SectorReader> sector_reader;
if(iso)
sector_reader = std::make_unique<Image_ISO_Form1Reader>(image_path);
else
sector_reader = std::make_unique<Image_BIN_Form1Reader>(image_path);

iso9660::PrimaryVolumeDescriptor pvd;
if(!iso9660::Browser::findDescriptor((iso9660::VolumeDescriptor &)pvd, sector_reader.get(), iso9660::VolumeDescriptorType::PRIMARY))
return;

auto root_directory = iso9660::Browser::rootDirectory(sector_reader.get(), pvd);
iso9660::Browser::iterate(root_directory, [&](const std::string &path, std::shared_ptr<iso9660::Entry> d)
{
auto fp((path.empty() ? "" : path + "/") + d->name());

files.emplace_back(d->sectorsOffset(), d->sectorsOffset() + d->sectorsSize());

return false;
});

std::fstream image_fs(image_path, std::fstream::in | std::fstream::binary);
if(!image_fs.is_open())
throw_line("unable to open file ({})", image_path);

std::fstream skeleton_fs(skeleton_path, std::fstream::out | std::fstream::binary);
if(!skeleton_fs.is_open())
throw_line("unable to create file ({})", skeleton_path.filename().string());

std::vector<uint8_t> data(iso ? FORM1_DATA_SIZE : CD_DATA_SIZE);
uint32_t sectors_count = std::filesystem::file_size(image_path) / data.size();
for(uint32_t i = 0; i < sectors_count; ++i)
{
image_fs.read((char *)data.data(), data.size());
if(image_fs.fail())
throw_line("read failed");

if(inside_range(i, files) != nullptr)
{
if(iso)
std::fill(data.begin(), data.end(), 0);
else
{
auto sector = (Sector *)data.data();

if(sector->header.mode == 1)
{
memset(sector->mode1.user_data, 0x00, FORM1_DATA_SIZE);
memset(&sector->mode1.ecc, 0x00, sizeof(Sector::ECC));
sector->mode1.edc = 0;
}
else if(sector->header.mode == 2)
{
if(sector->mode2.xa.sub_header.submode & (uint8_t)CDXAMode::FORM2)
{
memset(sector->mode2.xa.form2.user_data, 0x00, FORM2_DATA_SIZE);
sector->mode2.xa.form2.edc = 0;
}
else
{
memset(sector->mode2.xa.form1.user_data, 0x00, FORM1_DATA_SIZE);
memset(&sector->mode2.xa.form1.ecc, 0x00, sizeof(Sector::ECC));
sector->mode2.xa.form1.edc = 0;
}
}
}
}

skeleton_fs.write((char *)data.data(), data.size());
if(skeleton_fs.fail())
throw_line("write failed");
}
}


export void redumper_skeleton(Context &ctx, Options &options)
{
if(options.image_name.empty())
throw_line("image name is not provided");

auto image_prefix = (std::filesystem::path(options.image_path) / options.image_name).string();

if(std::filesystem::exists(image_prefix + ".cue"))
{
for(auto const &t : cue_get_entries(image_prefix + ".cue"))
{
// skip audio tracks
if(!t.second)
continue;

auto track_prefix = (std::filesystem::path(options.image_path) / std::filesystem::path(t.first).stem()).string();

skeleton(track_prefix, (std::filesystem::path(options.image_path) / t.first).string(), false, options);
}
}
else if(std::filesystem::exists(image_prefix + ".iso"))
{
skeleton(image_prefix, image_prefix + ".iso", true, options);
}
else
throw_line("image file not found");
}

}
5 changes: 3 additions & 2 deletions utils/misc.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,11 @@ export std::string ranges_to_string(const std::vector<std::pair<int32_t, int32_t
}


export const std::pair<int32_t, int32_t> *inside_range(int32_t lba, const std::vector<std::pair<int32_t, int32_t>> &ranges)
export template<typename T>
const std::pair<T, T> *inside_range(T value, const std::vector<std::pair<T, T>> &ranges)
{
for(auto const &r : ranges)
if(lba >= r.first && lba < r.second)
if(value >= r.first && value < r.second)
return &r;

return nullptr;
Expand Down

0 comments on commit 8592379

Please sign in to comment.