X-Git-Url: https://git.decadent.org.uk/gitweb/?p=videolink.git;a=blobdiff_plain;f=generate_dvd.cpp;h=32ce0f20a37a3cb580caf4ef4523e87a5a394ff2;hp=eeadc489bc1b75a92bae82a1dbc8cb3c2074f8ec;hb=4b8bff9ce93df43b120c5cf4d1476d3a435f99d3;hpb=c13714f6498df33e02635421354f5fb88a60eb3d diff --git a/generate_dvd.cpp b/generate_dvd.cpp index eeadc48..32ce0f2 100644 --- a/generate_dvd.cpp +++ b/generate_dvd.cpp @@ -1,4 +1,4 @@ -// Copyright 2005-6 Ben Hutchings . +// Copyright 2005-6 Ben Hutchings . // See the file "COPYING" for licence details. #include @@ -11,7 +11,7 @@ #include "xml_utils.hpp" dvd_contents::menu::menu() - : vob_temp(new temp_file("webdvd-vob-")) + : vob_temp(new temp_file("videolink-vob-")) { vob_temp->close(); } @@ -19,7 +19,7 @@ dvd_contents::menu::menu() void generate_dvd(const dvd_contents & contents, const std::string & output_dir) { - temp_file temp("webdvd-dvdauthor-"); + temp_file temp("videolink-dvdauthor-"); temp.close(); std::ofstream file(temp.get_name().c_str()); @@ -27,7 +27,8 @@ void generate_dvd(const dvd_contents & contents, // // g0: scratch // g1: current location - // g12: location that last jumped to a video + // g2: location that last jumped to a title + // g3: target chapter number // // All locations are divided into two bitfields: the least // significant 10 bits are a page/menu number and the most @@ -44,18 +45,18 @@ void generate_dvd(const dvd_contents & contents, " \n" " \n"; - for (unsigned menu_num = 0; - menu_num != contents.menus.size(); - ++menu_num) + for (unsigned menu_index = 0; + menu_index != contents.menus.size(); + ++menu_index) { - const dvd_contents::menu & menu = contents.menus[menu_num]; + const dvd_contents::menu & menu = contents.menus[menu_index]; - if (menu_num == 0) + if (menu_index == 0) { // This is the first (title) menu, displayed when the // disc is first played. file << - " \n" + " \n" "
\n"
 		// Initialise the current location if it is not set
 		// (all general registers are initially 0).
@@ -65,7 +66,7 @@ void generate_dvd(const dvd_contents & contents,
 	else
 	{
 	    file <<
-		"      \n"
+		"      \n"
 		"        
\n";
 	}
 
@@ -94,13 +95,13 @@ void generate_dvd(const dvd_contents & contents,
 	     menu_incr != 0;
 	     menu_incr /= 2)
 	{
-	    if (menu_num + menu_incr < contents.menus.size()
-		&& (menu_num & (menu_incr * 2 - 1)) == 0)
+	    if (menu_index + menu_incr < contents.menus.size()
+		&& (menu_index & (menu_incr * 2 - 1)) == 0)
 	    {
 		file <<
-		    "          if (g0 ge " << 1 + menu_num + menu_incr
+		    "          if (g0 ge " << 1 + menu_index + menu_incr
 					   << ")\n"
-		    "            jump menu " << 1 + menu_num + menu_incr
+		    "            jump menu " << 1 + menu_index + menu_incr
 					   << ";\n";
 	    }
 	}
@@ -111,12 +112,12 @@ void generate_dvd(const dvd_contents & contents,
 	    "        
\n" " \n"; - for (unsigned button_num = 0; - button_num != menu.entries.size(); - ++button_num) + for (unsigned button_index = 0; + button_index != menu.entries.size(); + ++button_index) { const dvd_contents::pgc_ref & target = - menu.entries[button_num]; + menu.entries[button_index]; file << " \n"; + file << "\n"; } - file << "
\n"; + file << + // Some DVD players don't seem to obey pause='inf' so make + // them loop. + " \n" + " jump cell 1;\n" + " \n" + "
\n"; } file << @@ -178,9 +188,9 @@ void generate_dvd(const dvd_contents & contents, // Generate a titleset for each title. This appears to make // jumping to titles a whole lot simpler (but limits us to 99 // titles). - for (unsigned title_num = 0; - title_num != contents.titles.size(); - ++title_num) + for (unsigned title_index = 0; + title_index != contents.titles.size(); + ++title_index) { file << " \n" @@ -193,11 +203,46 @@ void generate_dvd(const dvd_contents & contents, " \n" " \n" " \n" + "
\n"
 	    // Record calling location.
-	    "        
 g12 = g1; 
\n"; + " g2 = g1;\n"; + + // Count chapters in the title. + unsigned n_chapters = 0; + for (vob_list::const_iterator + it = contents.titles[title_index].begin(), + end = contents.titles[title_index].end(); + it != end; + ++it) + { + // Chapter start times may be specified in the "chapters" + // attribute as a comma-separated list. If this is not + // specified then the beginning of each file starts a new + // chapter. Thus the number of chapters in each file is + // the number of commas in the chapter attribute, plus 1. + ++n_chapters; + std::size_t pos = 0; + while ((pos = it->chapters.find(',', pos)) != std::string::npos) + { + ++n_chapters; + ++pos; + } + } + + // Generate jump "table" for chapters. + for (unsigned chapter_num = 1; + chapter_num <= n_chapters; + ++chapter_num) + file << + " if (g3 == " << chapter_num << ")\n" + " jump chapter " << chapter_num << ";\n"; + + file << + "
\n"; - for (vob_list::const_iterator it = contents.titles[title_num].begin(), - end = contents.titles[title_num].end(); + for (vob_list::const_iterator + it = contents.titles[title_index].begin(), + end = contents.titles[title_index].end(); it != end; ++it) { @@ -210,12 +255,15 @@ void generate_dvd(const dvd_contents & contents, } file << + " \n" // If the menu location has not been changed during // the title, set the location to be the following - // button in the menu. In any case, return to some - // menu. - " if (g1 eq g12) g1 = g1 + " << button_mult - << "; call menu; \n" + // button in the menu. + " if (g1 eq g2)\n" + " g1 = g1 + " << button_mult << ";\n" + // In any case, return to some menu. + " call menu;\n" + " \n" "
\n" "
\n" "
\n";