Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21863)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -775,6 +775,25 @@
 '/
 Declare Function openmpt_module_get_selected_subsong(ByVal module As openmpt_module Ptr) As Long
 
+/'* \brief Get the restart order of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_row
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_order(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+/'* \brief Get the restart row of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_order
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_row(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+
 /'* \brief Set Repeat Count
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21863)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -875,6 +875,26 @@
  * \since 0.3.0
  */
 LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod );
+
+/*! \brief Get the restart order of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_row
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong );
+/*! \brief Get the restart row of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_order
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong );
+
 /*! \brief Set Repeat Count
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21863)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -592,6 +592,26 @@
 	  \since 0.3.0
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_selected_subsong() const;
+
+	//! Get the restart order of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_row
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_order( std::int32_t subsong ) const;
+	//! Get the restart row of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_order
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	//! Set Repeat Count
 	/*!
 	  \param repeat_count Repeat Count
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -741,6 +741,26 @@
 	return -1;
 }
 
+int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_order( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
+int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_row( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
 int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -240,6 +240,13 @@
 	return impl->get_selected_subsong();
 }
 
+std::int32_t module::get_restart_order( std::int32_t subsong ) const {
+	return impl->get_restart_order( subsong );
+}
+std::int32_t module::get_restart_row( std::int32_t subsong ) const {
+	return impl->get_restart_row( subsong );
+}
+
 void module::set_repeat_count( std::int32_t repeat_count ) {
 	impl->set_repeat_count( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -306,11 +306,13 @@
 	m_sndFile->AddToLog( static_cast<OpenMPT::LogLevel>( loglevel ), mpt::transcode<mpt::ustring>( mpt::common_encoding::utf8, text ) );
 }
 
-module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence )
+module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order )
 	: duration(duration)
 	, start_row(start_row)
 	, start_order(start_order)
 	, sequence(sequence)
+	, restart_row(restart_row)
+	, restart_order(restart_order)
 {
 	return;
 }
@@ -436,7 +438,7 @@
 	for ( OpenMPT::SEQUENCEINDEX seq = 0; seq < m_sndFile->Order.GetNumSequences(); ++seq ) {
 		const std::vector<OpenMPT::GetLengthType> lengths = m_sndFile->GetLength( OpenMPT::eNoAdjust, OpenMPT::GetLengthTarget( true ).StartPos( seq, 0, 0 ) );
 		for ( const auto & l : lengths ) {
-			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq ) );
+			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq, l.restartRow, l.restartOrder ) );
 		}
 	}
 	return subsongs;
@@ -1093,6 +1095,24 @@
 std::int32_t module_impl::get_selected_subsong() const {
 	return m_current_subsong;
 }
+
+std::int32_t module_impl::get_restart_order( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_order;
+}
+std::int32_t module_impl::get_restart_row( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_row;
+}
+
 void module_impl::set_repeat_count( std::int32_t repeat_count ) {
 	m_sndFile->SetRepeatCount( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21863)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -107,7 +107,9 @@
 		std::int32_t start_row;
 		std::int32_t start_order;
 		std::int32_t sequence;
-		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence );
+		std::int32_t restart_row;
+		std::int32_t restart_order;
+		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order );
 	}; // struct subsong_data
 
 	typedef std::vector<subsong_data> subsongs_type;
@@ -198,6 +200,10 @@
 public:
 	void select_subsong( std::int32_t subsong );
 	std::int32_t get_selected_subsong() const;
+	
+	std::int32_t get_restart_order( std::int32_t subsong ) const;
+	std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	void set_repeat_count( std::int32_t repeat_count );
 	std::int32_t get_repeat_count() const;
 	double get_duration_seconds() const;
