From 181e3010eb74af0a70df3c40e84bfad42a9d2ebb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 6 Aug 2006 12:19:38 +0000 Subject: [PATCH] Implemented jumping to chapters by setting a register in each button linking to a title and adding a jump table to each title's pre routine. Changed index variable naming to use _index suffix if 0-based and _num suffix if 1-based. --- TODO | 1 - generate_dvd.cpp | 124 +++++++++++++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 43 deletions(-) diff --git a/TODO b/TODO index 1c64870..7bf02e2 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ Priority 1 (highest) Investigate and fix the crash that occurs after we trigger exit from null_prompt_service. -Make linking to chapters actually work. Priority 2 Use ffmpeg to convert unsuitable video files (how do we check this?). diff --git a/generate_dvd.cpp b/generate_dvd.cpp index 9f15d2f..6c507b9 100644 --- a/generate_dvd.cpp +++ b/generate_dvd.cpp @@ -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,13 +45,13 @@ 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. @@ -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 << @@ -186,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" @@ -201,11 +203,46 @@ void generate_dvd(const dvd_contents & contents, " \n" " \n" " \n" + "
\n"
 	    // Record calling location.
-	    "        
 g12 = g1; 
\n"; + " g2 = g1;\n"; - for (vob_list::const_iterator it = contents.titles[title_num].begin(), - end = contents.titles[title_num].end(); + // 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_index].begin(), + end = contents.titles[title_index].end(); it != end; ++it) { @@ -218,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"; -- 2.39.2