Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package redumper for openSUSE:Factory 
checked in at 2026-07-20 09:59:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/redumper (Old)
 and      /work/SRC/openSUSE:Factory/.redumper.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "redumper"

Mon Jul 20 09:59:15 2026 rev:8 rq:1366616 version:734

Changes:
--------
--- /work/SRC/openSUSE:Factory/redumper/redumper.changes        2026-07-06 
15:00:33.098513330 +0200
+++ /work/SRC/openSUSE:Factory/.redumper.new.24530/redumper.changes     
2026-07-20 10:01:25.276332466 +0200
@@ -1,0 +2,11 @@
+Sun Jul 19 08:03:24 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 734
+  * Update recommended OmniDrive version.
+  * Fix off by one in joliet UCS-2BE to UTF-8 conversion code.
+  * Remove xml tags from dvd key printing.
+  * Implement generic drive lead-in reading.
+  * Automatic sector order detection for generic drives.
+  * Support hp rebadges in flash_tsst.
+
+-------------------------------------------------------------------

Old:
----
  redumper-b729.tar.gz

New:
----
  redumper-b734.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ redumper.spec ++++++
--- /var/tmp/diff_new_pack.cQtpv1/_old  2026-07-20 10:01:25.892353198 +0200
+++ /var/tmp/diff_new_pack.cQtpv1/_new  2026-07-20 10:01:25.896353332 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           redumper
-Version:        729
+Version:        734
 Release:        0
 Summary:        Low level CD dumper utility
 License:        GPL-3.0-only

++++++ redumper-b729.tar.gz -> redumper-b734.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/CMakeLists.txt 
new/redumper-b734/CMakeLists.txt
--- old/redumper-b729/CMakeLists.txt    2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/CMakeLists.txt    2026-07-18 13:19:20.000000000 +0200
@@ -35,13 +35,21 @@
 # C/C++
 set(CMAKE_CXX_STANDARD 20)
 
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    option(REDUMPER_CLANG_USE_LIBCPP "Link to libc++ instead of system 
default" OFF)
+
+    if(REDUMPER_CLANG_USE_LIBCPP)
+        add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>)
+        add_link_options(-stdlib=libc++)
+    endif()
+
+    add_link_options(${REDUMPER_CLANG_LINK_OPTIONS})
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
     add_compile_options(-Wall -Wextra -Werror)
 
     # remove after https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99426 is fixed
     add_compile_options(--param=ggc-min-expand=10000)
-endif()
-if(MSVC)
+elseif(MSVC)
     # build MT configuration by default
     set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
 
@@ -110,6 +118,7 @@
     "crc/crc.ixx"
     "crc/crc16_gsm.ixx"
     "crc/crc32.ixx"
+    "drive/detect.ixx"
     "drive/flash_mt1959.ixx"
     "drive/flash_plextor.ixx"
     "drive/flash_sd616.ixx"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/cd/cd_dump_extra.ixx 
new/redumper-b734/cd/cd_dump_extra.ixx
--- old/redumper-b729/cd/cd_dump_extra.ixx      2026-07-05 18:46:51.000000000 
+0200
+++ new/redumper-b734/cd/cd_dump_extra.ixx      2026-07-18 13:19:20.000000000 
+0200
@@ -309,6 +309,93 @@
 }
 
 
+void generic_process_leadin(Context &ctx, const TOC &toc, std::fstream 
&fs_scram, std::fstream &fs_state, std::fstream &fs_subcode, Options &options)
+{
+    if(toc.sessions.empty() || toc.sessions.front().tracks.size() <= 1)
+        return;
+
+    auto &t = toc.sessions.front().tracks.front();
+    if(!(t.control & (uint8_t)ChannelQ::Control::DATA))
+        return;
+
+    int32_t track1_end = toc.sessions.front().tracks[1].lba_start;
+    auto write_offset = track_offset_by_sync(t.lba_start, track1_end, 
fs_state, fs_scram);
+    if(!write_offset)
+        return;
+
+    int32_t combined_offset = *write_offset + ctx.drive_config.read_offset;
+    if(combined_offset >= 0 || combined_offset < -134 * 
(int32_t)CD_DATA_SIZE_SAMPLES)
+        return;
+
+    // read from preceding sector up to and including start of first track
+    int32_t read_lba = sample_to_lba(*write_offset, 0) - 1;
+    uint32_t read_count = t.lba_start - read_lba + 1;
+
+    // check if lead-in samples are needed
+    uint32_t sample_index = sample_offset_r2a(lba_to_sample(read_lba, 
-ctx.drive_config.read_offset));
+    uint32_t samples_count = read_count * CD_DATA_SIZE_SAMPLES;
+    std::vector<State> existing_state(samples_count);
+    read_entry(fs_state, (uint8_t *)existing_state.data(), sizeof(State), 
sample_index, samples_count, 0, (uint8_t)State::ERROR_SKIP);
+    if(std::none_of(existing_state.begin(), existing_state.end(), [](State s) 
{ return s == State::ERROR_SKIP || s == State::ERROR_C2; }))
+        return;
+
+    auto layout = sector_order_layout(ctx.drive_config.sector_order);
+    std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE * read_count);
+    auto error_field = layout.c2_offset == CD_RAW_DATA_SIZE ? 
READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2;
+    auto sub_channel = layout.subcode_offset == CD_RAW_DATA_SIZE ? 
READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW;
+
+    SPTD::Status status = cmd_read_cd(*ctx.sptd, sector_buffer.data(), 
CD_RAW_DATA_SIZE, read_lba, read_count, READ_CD_ExpectedSectorType::CD_DA, 
error_field, sub_channel);
+    if(status.status_code)
+        status = cmd_read_cd(*ctx.sptd, sector_buffer.data(), 
CD_RAW_DATA_SIZE, read_lba, read_count, READ_CD_ExpectedSectorType::ALL_TYPES, 
error_field, sub_channel);
+
+    if(status.status_code)
+    {
+        if(options.verbose)
+            LOG("GENERIC: lead-in read failed (LBA: {:6}, sectors: {}, SCSI: 
{})", read_lba, read_count, SPTD::StatusMessage(status));
+        return;
+    }
+
+    LOG("GENERIC: storing lead-in (LBA: {:6}, sectors: {})", read_lba, 
read_count);
+
+    std::vector<State> state_buffer(read_count * CD_DATA_SIZE_SAMPLES);
+    std::vector<uint8_t> data_buffer(read_count * CD_DATA_SIZE);
+    std::vector<uint8_t> subcode_buffer(read_count * CD_SUBCODE_SIZE);
+
+    for(uint32_t i = 0; i < read_count; ++i)
+    {
+        auto raw = sector_buffer.data() + layout.size * i;
+
+        std::span<State> sector_state(&state_buffer[i * CD_DATA_SIZE_SAMPLES], 
CD_DATA_SIZE_SAMPLES);
+        std::span<uint8_t> sector_data(&data_buffer[i * CD_DATA_SIZE], 
CD_DATA_SIZE);
+        std::span<uint8_t> sector_subcode(&subcode_buffer[i * 
CD_SUBCODE_SIZE], CD_SUBCODE_SIZE);
+
+        if(layout.c2_offset != CD_RAW_DATA_SIZE)
+        {
+            auto sector_state_c2 = c2_to_state(raw + layout.c2_offset, 
State::SUCCESS);
+            std::copy(sector_state_c2.begin(), sector_state_c2.end(), 
sector_state.begin());
+
+            if(options.verbose)
+            {
+                uint32_t c2_bits = c2_bits_count(std::span<const uint8_t>(raw 
+ layout.c2_offset, CD_C2_SIZE));
+                if(c2_bits)
+                    LOGC_R("[LBA: {:6}] C2 error (bits: {:4})", read_lba + 
(int32_t)i, c2_bits);
+            }
+        }
+        else
+            std::fill(sector_state.begin(), sector_state.end(), 
State::SUCCESS_C2_OFF);
+
+        if(layout.data_offset != CD_RAW_DATA_SIZE)
+            std::copy(raw + layout.data_offset, raw + layout.data_offset + 
CD_DATA_SIZE, sector_data.begin());
+
+        if(layout.subcode_offset != CD_RAW_DATA_SIZE)
+            std::copy(raw + layout.subcode_offset, raw + layout.subcode_offset 
+ CD_SUBCODE_SIZE, sector_subcode.begin());
+    }
+
+    store_data(fs_scram, fs_state, data_buffer, state_buffer, 
lba_to_sample(read_lba, -ctx.drive_config.read_offset));
+    store_subcode(fs_subcode, subcode_buffer, read_lba);
+}
+
+
 export int redumper_dump_extra(Context &ctx, Options &options)
 {
     int exit_code = 0;
@@ -334,6 +421,11 @@
         if(!options.mediatek_skip_leadout && 
!is_omnidrive_firmware(ctx.drive_config))
             mediatek_process_leadout(ctx, toc, fs_scram, fs_state, fs_subcode, 
options);
     }
+    else if(ctx.drive_config.type == Type::GENERIC)
+    {
+        if(!options.generic_skip_leadin)
+            generic_process_leadin(ctx, toc, fs_scram, fs_state, fs_subcode, 
options);
+    }
 
     return exit_code;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/drive/detect.ixx 
new/redumper-b734/drive/detect.ixx
--- old/redumper-b729/drive/detect.ixx  1970-01-01 01:00:00.000000000 +0100
+++ new/redumper-b734/drive/detect.ixx  2026-07-18 13:19:20.000000000 +0200
@@ -0,0 +1,107 @@
+module;
+#include <algorithm>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+export module drive.detect;
+
+import cd.cd;
+import cd.common;
+import cd.subcode;
+import cd.toc;
+import common;
+import drive;
+import options;
+import scsi.cmd;
+import scsi.mmc;
+import scsi.sptd;
+import utils.logger;
+import utils.strings;
+
+
+namespace gpsxre
+{
+
+
+export bool detect_sector_order(SPTD &sptd, DriveConfig &drive_config, int32_t 
lba)
+{
+    std::vector<uint8_t> sector_buffer(CD_RAW_DATA_SIZE);
+
+    for(auto const &order : SECTOR_ORDER_STRING)
+    {
+        auto test_layout = sector_order_layout(order.first);
+
+        auto error_field = test_layout.c2_offset == CD_RAW_DATA_SIZE ? 
READ_CD_ErrorField::NONE : READ_CD_ErrorField::C2;
+        auto sub_channel = test_layout.subcode_offset == CD_RAW_DATA_SIZE ? 
READ_CD_SubChannel::NONE : READ_CD_SubChannel::RAW;
+
+        // try read as-audio first, then fallback to as-data
+        auto status = cmd_read_cd(sptd, sector_buffer.data(), 
CD_RAW_DATA_SIZE, lba, 1, READ_CD_ExpectedSectorType::CD_DA, error_field, 
sub_channel);
+        if(status.status_code)
+            status = cmd_read_cd(sptd, sector_buffer.data(), CD_RAW_DATA_SIZE, 
lba, 1, READ_CD_ExpectedSectorType::ALL_TYPES, error_field, sub_channel);
+        if(status.status_code)
+            continue;
+
+        // validate by checking subcode Q CRC at the expected offset
+        if(test_layout.subcode_offset != CD_RAW_DATA_SIZE)
+        {
+            if(subcode_extract_q(sector_buffer.data() + 
test_layout.subcode_offset).isValid())
+            {
+                // C2 should be zeroed assuming a clean first sector
+                if(test_layout.c2_offset != CD_RAW_DATA_SIZE)
+                {
+                    auto c2_start = sector_buffer.data() + 
test_layout.c2_offset;
+                    if(std::any_of(c2_start, c2_start + CD_C2_SIZE, [](uint8_t 
v) { return v != 0; }))
+                        continue;
+                }
+
+                drive_config.sector_order = order.first;
+                LOG("GENERIC: auto-detected sector order: {}", order.second);
+                return true;
+            }
+        }
+        else
+        {
+            // no subcode, validate DATA_C2 order
+            if(test_layout.c2_offset != CD_RAW_DATA_SIZE)
+            {
+                auto c2_start = sector_buffer.data() + test_layout.c2_offset;
+                if(std::all_of(c2_start, c2_start + CD_C2_SIZE, [](uint8_t v) 
{ return v == 0; }))
+                {
+                    drive_config.sector_order = order.first;
+                    LOG("GENERIC: auto-detected sector order: {} (no subcode 
validation)", order.second);
+                    return true;
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+
+export int redumper_drive_detect(Context &ctx, Options &options)
+{
+    int exit_code = 0;
+
+    if(ctx.disc_type != DiscType::CD)
+        return exit_code;
+
+    if(ctx.drive_config.type == Type::GENERIC && ctx.drive_config.read_method 
== ReadMethod::BE && !options.drive_sector_order)
+    {
+        auto toc_buffer = toc_read(*ctx.sptd);
+        TOC toc(toc_buffer, false);
+        if(toc.sessions.empty() || toc.sessions.front().tracks.empty())
+        {
+            LOG("warning: sector order detection failed (TOC has no tracks), 
using default");
+            return exit_code;
+        }
+        int32_t lba = toc.sessions.front().tracks.front().lba_start;
+        if(!detect_sector_order(*ctx.sptd, ctx.drive_config, lba))
+            LOG("warning: sector order detection failed, using default");
+    }
+
+    return exit_code;
+}
+
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/drive/flash_tsst.ixx 
new/redumper-b734/drive/flash_tsst.ixx
--- old/redumper-b729/drive/flash_tsst.ixx      2026-07-05 18:46:51.000000000 
+0200
+++ new/redumper-b734/drive/flash_tsst.ixx      2026-07-18 13:19:20.000000000 
+0200
@@ -21,6 +21,8 @@
 namespace gpsxre
 {
 
+const std::set<std::string> TSST_SUPPORTED_VENDORS = { "TSSTcorp", "hp" };
+
 const std::set<std::string> TSST_SUPPORTED_DRIVES = { "DVD-ROM SH-D163A", 
"DVD-ROM SH-D163B", "DVD-ROM SH-D162C", "DVD-ROM SH-D163C", "DVD-ROM SH-D162D", 
"DVD-ROM TS-H353A", "DVD-ROM TS-H353B",
     "DVD-ROM TS-H353C", "DVD-ROM TS-H352C", "DVD-ROM TS-H352D", "DVD-ROM 
SH-116AB", "DVD-ROM SH-118CB" };
 
@@ -50,7 +52,7 @@
 {
     int exit_code = 0;
 
-    if(!options.force_flash && (ctx.drive_config.vendor_id != "TSSTcorp" || 
!TSST_SUPPORTED_DRIVES.contains(ctx.drive_config.product_id)))
+    if(!options.force_flash && 
(!TSST_SUPPORTED_VENDORS.contains(ctx.drive_config.vendor_id) || 
!TSST_SUPPORTED_DRIVES.contains(ctx.drive_config.product_id)))
         throw_line("flashing of this drive is unsupported");
 
     // block size is how much data is sent in one command, potentially it can 
vary but current value is taken from the original flasher
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/drive.ixx new/redumper-b734/drive.ixx
--- old/redumper-b729/drive.ixx 2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/drive.ixx 2026-07-18 13:19:20.000000000 +0200
@@ -112,7 +112,7 @@
 };
 
 
-static const std::map<SectorOrder, std::string> SECTOR_ORDER_STRING = {
+export const std::map<SectorOrder, std::string> SECTOR_ORDER_STRING = {
     { SectorOrder::DATA_C2_SUB, "DATA_C2_SUB" },
     { SectorOrder::DATA_SUB_C2, "DATA_SUB_C2" },
     { SectorOrder::DATA_SUB,    "DATA_SUB"    },
@@ -474,7 +474,7 @@
 
 export uint32_t omnidrive_minimum_version()
 {
-    return 0x00010002;
+    return 0x00010004;
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/dvd/dvd_dump.ixx 
new/redumper-b734/dvd/dvd_dump.ixx
--- old/redumper-b729/dvd/dvd_dump.ixx  2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/dvd/dvd_dump.ixx  2026-07-18 13:19:20.000000000 +0200
@@ -808,7 +808,10 @@
 
     std::vector<Range<int32_t>> protection;
 
-    bool omnidrive_firmware = is_omnidrive_firmware(ctx.drive_config) != 
std::nullopt;
+    auto omnidrive_version = is_omnidrive_firmware(ctx.drive_config);
+    if(omnidrive_version && *omnidrive_version == 0x00010003)
+        throw_line("unsupported OmniDrive version for DVD dumping, upgrade to 
{}", omnidrive_version_string(omnidrive_minimum_version()));
+    bool omnidrive_firmware = omnidrive_version != std::nullopt;
     bool kreon_firmware = is_kreon_firmware(ctx.drive_config);
     bool kreon_locked = false;
 
@@ -1139,7 +1142,7 @@
     uint32_t refine_retries = options.retries ? options.retries : 1;
 
     FilesystemContext fs_ctx;
-    ROMEntry rom_entry(image_prefix + dump_get_config(ctx.disc_type, 
false).image_extension);
+    ROMEntry rom_entry(options.image_name + dump_get_config(ctx.disc_type, 
false).image_extension);
     bool rom_update = dump;
 
     SignalINT signal;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/dvd/dvd_key.ixx 
new/redumper-b734/dvd/dvd_key.ixx
--- old/redumper-b729/dvd/dvd_key.ixx   2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/dvd/dvd_key.ixx   2026-07-18 13:19:20.000000000 +0200
@@ -125,7 +125,7 @@
 
         std::string protection("unknown");
         if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::NONE)
-            protection = "<none>";
+            protection = "NONE";
         else if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::CSS_CPPM)
             protection = "CSS/CPPM";
         else if(cpst == READ_DVD_STRUCTURE_CopyrightInformation_CPST::CPRM)
@@ -180,9 +180,9 @@
                 {
                     std::string title_key;
                     if(t.second.empty())
-                        title_key = "<error>";
+                        title_key = "(error)";
                     else if(is_zeroed(t.second.data(), t.second.size()))
-                        title_key = "<none>";
+                        title_key = "N/A";
                     else
                         title_key = 
std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", t.second[0], t.second[1], 
t.second[2], t.second[3], t.second[4]);
 
@@ -234,9 +234,9 @@
         {
             std::string title_key;
             if(t.second.empty())
-                title_key = "<error>";
+                title_key = "(error)";
             else if(is_zeroed(t.second.data(), t.second.size()))
-                title_key = "<none>";
+                title_key = "N/A";
             else
                 title_key = std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", 
t.second[0], t.second[1], t.second[2], t.second[3], t.second[4]);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/filesystem/iso9660/iso9660_defs.ixx 
new/redumper-b734/filesystem/iso9660/iso9660_defs.ixx
--- old/redumper-b729/filesystem/iso9660/iso9660_defs.ixx       2026-07-05 
18:46:51.000000000 +0200
+++ new/redumper-b734/filesystem/iso9660/iso9660_defs.ixx       2026-07-18 
13:19:20.000000000 +0200
@@ -382,7 +382,7 @@
         utf16_identifier[i] = endian_swap(identifier[i]);
 
     std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> 
convert("", u"");
-    std::string utf8_identifier = convert.to_bytes(utf16_identifier, 
&utf16_identifier[N - 1]);
+    std::string utf8_identifier = convert.to_bytes(utf16_identifier, 
&utf16_identifier[N]);
 
     return trim(utf8_identifier).c_str();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/options.ixx 
new/redumper-b734/options.ixx
--- old/redumper-b729/options.ixx       2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/options.ixx       2026-07-18 13:19:20.000000000 +0200
@@ -44,6 +44,7 @@
     std::unique_ptr<int> drive_pregap_start;
     std::unique_ptr<std::string> drive_read_method;
     std::unique_ptr<std::string> drive_sector_order;
+    bool auto_detect;
     std::unique_ptr<double> speed;
     int retries;
     bool refine_subchannel;
@@ -62,6 +63,7 @@
     bool plextor_leadin_force_store;
     bool mediatek_skip_leadout;
     int mediatek_leadout_retries;
+    bool generic_skip_leadin;
     bool kreon_partial_ss;
     bool dvd_raw;
     bool bd_raw;
@@ -106,6 +108,7 @@
         , overwrite(false)
         , force_split(false)
         , leave_unchanged(false)
+        , auto_detect(false)
         , retries(retries_default)
         , refine_subchannel(false)
         , refine_sector_mode(false)
@@ -119,6 +122,7 @@
         , plextor_leadin_force_store(false)
         , mediatek_skip_leadout(false)
         , mediatek_leadout_retries(mediatek_leadout_retries_default)
+        , generic_skip_leadin(false)
         , kreon_partial_ss(false)
         , dvd_raw(false)
         , bd_raw(false)
@@ -230,6 +234,8 @@
                         drive_sector_order = std::make_unique<std::string>();
                         s_value = drive_sector_order.get();
                     }
+                    else if(key == "--auto-detect")
+                        auto_detect = true;
                     else if(key == "--speed")
                     {
                         speed = std::make_unique<double>();
@@ -278,6 +284,8 @@
                         mediatek_skip_leadout = true;
                     else if(key == "--mediatek-leadout-retries")
                         i_value = &mediatek_leadout_retries;
+                    else if(key == "--generic-skip-leadin")
+                        generic_skip_leadin = true;
                     else if(key == "--kreon-partial-ss")
                         kreon_partial_ss = true;
                     else if(key == "--dvd-raw")
@@ -422,17 +430,18 @@
         LOG("\t--drive-pregap-start=VALUE      \toverride drive pre-gap start 
LBA");
         LOG("\t--drive-read-method=VALUE       \toverride drive read method, 
possible values: BE, D8, BE_CDDA");
         LOG("\t--drive-sector-order=VALUE      \toverride drive sector order, 
possible values: DATA_C2_SUB, DATA_SUB_C2, DATA_SUB, DATA_C2");
+        LOG("\t--auto-detect                   \tattempt to automatically 
detect drive sector order for generic drives");
         LOG("");
         LOG("\t(drive specific)");
         LOG("\t--plextor-skip-leadin           \tskip dumping lead-in using 
negative range");
         LOG("\t--plextor-leadin-retries=VALUE  \tmaximum number of lead-in 
retries per session (default: {})", plextor_leadin_retries_default);
         LOG("\t--plextor-leadin-force-store    \tstore unverified lead-in");
+        LOG("\t--mediatek-skip-leadout         \tskip extracting lead-out from 
drive cache");
+        LOG("\t--mediatek-leadout-retries      \tnumber of preceding lead-out 
sector reads to fill up the cache (default: {})", 
mediatek_leadout_retries_default);
+        LOG("\t--generic-skip-leadin           \tskip dumping lead-in for 
negative offset discs on generic drives");
         LOG("\t--kreon-partial-ss              \tget minimal security sector 
(fixes bad firmware)");
         LOG("\t--dvd-raw                       \tdump raw DVD sectors 
(OmniDrive)");
         LOG("\t--bd-raw                        \tdump raw BD sectors 
(OmniDrive)");
-
-        LOG("\t--mediatek-skip-leadout         \tskip extracting lead-out from 
drive cache");
-        LOG("\t--mediatek-leadout-retries      \tnumber of preceding lead-out 
sector reads to fill up the cache (default: {})", 
mediatek_leadout_retries_default);
         LOG("\t--disable-cdtext                \tdisable CD-TEXT reading");
         LOG("");
         LOG("\t(offset)");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redumper-b729/redumper.ixx 
new/redumper-b734/redumper.ixx
--- old/redumper-b729/redumper.ixx      2026-07-05 18:46:51.000000000 +0200
+++ new/redumper-b734/redumper.ixx      2026-07-18 13:19:20.000000000 +0200
@@ -26,6 +26,7 @@
 import common;
 import debug;
 import drive;
+import drive.detect;
 import drive.flash.mt1959;
 import drive.flash.plextor;
 import drive.flash.tsst;
@@ -145,6 +146,7 @@
     { "fixmsf",         { false, false, false, true, false, redumper_fix_msf } 
      },
     { "debug::flip",    { false, false, false, true, false, redumper_flip }    
      },
     { "drive::test",    { true, true, true, false, false, redumper_drive_test 
}      },
+    { "drive::detect",  { true, true, true, false, false, 
redumper_drive_detect }    },
 };
 
 
@@ -260,6 +262,8 @@
     std::list<std::string> cd_commands{ "dump", "dump::extra", "protection", 
"refine", "dvdkey", "split", "hash", "info" };
     if(options.rings)
         cd_commands.insert(cd_commands.begin(), "rings");
+    if(options.auto_detect)
+        cd_commands.insert(cd_commands.begin(), "drive::detect");
     if(options.auto_eject)
     {
         if(auto it = std::find(cd_commands.begin(), cd_commands.end(), 
"split"); it != cd_commands.end())
@@ -274,7 +278,7 @@
     {
         for(auto it = cd_commands.begin(); it != cit;)
         {
-            if(*it == "rings" && std::find(cit, cd_commands.end(), "dump") != 
cd_commands.end() || *it == "protection")
+            if(*it == "rings" && std::find(cit, cd_commands.end(), "dump") != 
cd_commands.end() || *it == "protection" || *it == "drive::detect")
                 ++it;
             else
                 it = cd_commands.erase(it);

Reply via email to