Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DC system to info #183

Merged
merged 3 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ target_sources(redumper
"systems/securom.ixx"
"systems/s_cdrom.ixx"
"systems/s_iso.ixx"
"systems/dc.ixx"
"systems/mcd.ixx"
"systems/psx.ixx"
"systems/ps2.ixx"
Expand Down
177 changes: 177 additions & 0 deletions systems/dc.ixx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
module;

#include <cctype>
#include <cstdint>
#include <filesystem>
#include <format>
#include <fstream>
#include <map>
#include <ostream>
#include <set>
#include <string_view>
#include <vector>
#include "system.hh"

export module systems.dc;

import filesystem.iso9660;
import readers.sector_reader;
import utils.hex_bin;
import utils.misc;
import utils.strings;



namespace gpsxre
{

export class SystemDC : public System
{
public:
std::string getName() override
{
return "DC";
}

Type getType() override
{
return Type::ISO;
}

void printInfo(std::ostream &os, SectorReader *sector_reader, const std::filesystem::path &) const override
{
auto system_area = iso9660::Browser::readSystemArea(sector_reader);
if(system_area.size() < _ROM_HEADER_OFFSET + sizeof(ROMHeader) || memcmp(system_area.data(), _SYSTEM_MAGIC.data(), _SYSTEM_MAGIC.size()))
return;

std::vector<uint8_t> rom_header_data(system_area.data() + _ROM_HEADER_OFFSET, system_area.data() + _ROM_HEADER_OFFSET + sizeof(ROMHeader));

auto rom_header = (ROMHeader *)rom_header_data.data();

std::string date = extractDate(std::string(rom_header->date, sizeof(rom_header->date)));
if(!date.empty())
os << std::format(" build date: {}", date) << std::endl;

std::string version = extractVersion(std::string(rom_header->version, sizeof(rom_header->version)));
if(!version.empty())
os << std::format(" version: {}", version) << std::endl;

std::string serial(rom_header->serial, sizeof(rom_header->serial));
erase_all_inplace(serial, ' ');
if(!serial.empty())
os << std::format(" serial: {}", serial) << std::endl;

std::string regions(rom_header->regions, sizeof(rom_header->regions));
erase_all_inplace(regions, ' ');

std::set<std::string> unique_regions;
for(auto r : regions)
{
auto it = _REGIONS.find(r);
if(it != _REGIONS.end())
unique_regions.insert(it->second);
}

if(!unique_regions.empty())
{
os << (unique_regions.size() == 1 ? " region: " : " regions: ");
bool comma = false;
for(auto r : unique_regions)
{
os << (comma ? ", " : "") << r;
comma = true;
}
os << std::endl;
}

os << " header:" << std::endl;
os << std::format("{}", hexdump(system_area.data(), _ROM_HEADER_OFFSET, sizeof(ROMHeader)));
}

private:
static constexpr std::string_view _SYSTEM_MAGIC = "SEGA SEGAKATANA";
static constexpr uint32_t _ROM_HEADER_OFFSET = 0x000;
static constexpr uint32_t _DATE_SYMBOLS = 8;
static constexpr uint32_t _YEAR_SYMBOLS = 4;
static constexpr uint32_t _MONTH_SYMBOLS = 2;
static constexpr uint32_t _DAY_SYMBOLS = 2;
static constexpr uint32_t _VERSION_SYMBOLS = 6;
static const std::map<char, std::string> _REGIONS;

struct ROMHeader
{
char system_name[16];
char maker_id[16];
char device_info[16];

char regions[3];
char reserved1[5];
char peripherals[8];

char serial[10];
char version[6];

char date[8];
char reserved2[8];

char exe_filename[16];
char disc_manufacturer[16];

char title[128];
};


std::string extractDate(std::string date) const
{
if(date.length() != _DATE_SYMBOLS)
return "";

auto year_index = str_to_uint64(std::string(date, 0, _YEAR_SYMBOLS));
if(!year_index || !number_is_year(*year_index))
return "";

auto month_index = str_to_uint64(std::string(date, 4, _MONTH_SYMBOLS));
if(!month_index || !number_is_month(*month_index))
return "";

auto day_index = str_to_uint64(std::string(date, 6, _DAY_SYMBOLS));
if(!day_index || !number_is_day(*day_index))
return "";

date.insert(4, "-");
date.insert(7, "-");

return date;
}


std::string extractVersion(std::string version) const
{
if(version.length() != _VERSION_SYMBOLS)
return "";

if(version[0] != 'V')
return "";

version.erase(0, 1);
erase_all_inplace(version, ' ');

for(uint32_t i = 0; i < version.length(); ++i)
{
char ch = version[i];
if(!std::isdigit(ch) && ch != '.')
return "";
}

return version;
}
};


const std::map<char, std::string> SystemDC::_REGIONS = {
{ 'J', "Japan" },
{ 'U', "USA" },
{ 'E', "Europe" }
};

}
2 changes: 2 additions & 0 deletions systems/systems.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export module systems.systems;

import systems.cdrom;
import systems.iso;
import systems.dc;
import systems.mcd;
import systems.psx;
import systems.ps2;
Expand Down Expand Up @@ -36,6 +37,7 @@ public:
systems.push_back([]() { return std::make_unique<SystemCDROM>(); });
systems.push_back([]() { return std::make_unique<SystemSecuROM>(); });
systems.push_back([]() { return std::make_unique<SystemISO>(); });
systems.push_back([]() { return std::make_unique<SystemDC>(); });
systems.push_back([]() { return std::make_unique<SystemMCD>(); });
systems.push_back([]() { return std::make_unique<SystemPSX>(); });
systems.push_back([]() { return std::make_unique<SystemPS2>(); });
Expand Down
6 changes: 6 additions & 0 deletions utils/misc.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,10 @@ export bool number_is_month(uint32_t month)
return month >= 1 && month <= 12;
}


export bool number_is_day(uint32_t day)
{
return day >= 1 && day <= 31;
}

}