From 4f54781c31d34874dbb23aab672ea248795c5245 Mon Sep 17 00:00:00 2001 From: Tamas Kalman Date: Fri, 26 Dec 2025 00:59:04 -0800 Subject: [PATCH 1/2] Add --output-start-date and --output-stop-date parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These new parameters control frame output timing while still simulating the full repository history. Unlike --start-date/--stop-date which filter log entries, these options: - --output-start-date: Start outputting frames from this date - --output-stop-date: Stop outputting frames after this date Key behavior: - Gource simulates the full history internally (files/avatars positioned correctly) - Only outputs frames within the specified date range - Useful for rendering segments of long repository histories efficiently This enables rendering weekly/monthly video segments without processing the entire history multiple times. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/gource.cpp | 18 +++++++++++++- src/gource_settings.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ src/gource_settings.h | 5 ++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/gource.cpp b/src/gource.cpp index cf86c4f9..4ca9b7bc 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -271,7 +271,23 @@ void Gource::update(float t, float dt) { //extract frames based on frameskip setting if frameExporter defined if(frameExporter != 0 && commitlog && !gGourceSettings.shutdown) { if(framecount % (frameskip+1) == 0) { - frameExporter->dump(); + // Check if current simulation time is within output date range + bool in_output_range = true; + + // Skip frames before output-start-date + if(gGourceSettings.output_start_timestamp != 0 && currtime < gGourceSettings.output_start_timestamp) { + in_output_range = false; + } + + // Skip frames after output-stop-date and mark as finished + if(gGourceSettings.output_stop_timestamp != 0 && currtime > gGourceSettings.output_stop_timestamp) { + in_output_range = false; + stop_position_reached = true; + } + + if(in_output_range) { + frameExporter->dump(); + } } } diff --git a/src/gource_settings.cpp b/src/gource_settings.cpp index 76ec9479..f2661c73 100644 --- a/src/gource_settings.cpp +++ b/src/gource_settings.cpp @@ -63,6 +63,10 @@ void GourceSettings::help(bool extended_help) { printf(" --start-date 'YYYY-MM-DD hh:mm:ss +tz' Start at a date and optional time\n"); printf(" --stop-date 'YYYY-MM-DD hh:mm:ss +tz' Stop at a date and optional time\n\n"); + printf(" --output-start-date 'YYYY-MM-DD hh:mm:ss +tz'\n"); + printf(" Start outputting frames from this date\n"); + printf(" --output-stop-date 'YYYY-MM-DD hh:mm:ss +tz'\n"); + printf(" Stop outputting frames after this date\n\n"); printf(" -p, --start-position POSITION Start at some position (0.0-1.0 or 'random')\n"); printf(" --stop-position POSITION Stop at some position\n"); printf(" -t, --stop-at-time SECONDS Stop after a specified number of seconds\n"); @@ -340,6 +344,8 @@ GourceSettings::GourceSettings() { arg_types["start-position"] = "string"; arg_types["start-date"] = "string"; arg_types["stop-date"] = "string"; + arg_types["output-start-date"] = "string"; + arg_types["output-stop-date"] = "string"; arg_types["stop-position"] = "string"; arg_types["crop"] = "string"; arg_types["hide"] = "string"; @@ -390,6 +396,12 @@ void GourceSettings::setGourceDefaults() { stop_timestamp = 0; stop_date = ""; + output_start_timestamp = 0; + output_start_date = ""; + + output_stop_timestamp = 0; + output_stop_date = ""; + start_position = 0.0f; stop_position = 0.0f; stop_at_time = -1.0f; @@ -1311,6 +1323,49 @@ void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gourc } } + if((entry = gource_settings->getEntry("output-start-date")) != 0) { + + if(!entry->hasValue()) conffile.entryException(entry, "specify output-start-date (YYYY-MM-DD hh:mm:ss)"); + + std::string output_start_date_string = entry->getString(); + + if(parseDateTime(output_start_date_string, output_start_timestamp)) { + + char datestr[256]; + strftime(datestr, 256, "%Y-%m-%d", localtime ( &output_start_timestamp )); + output_start_date = datestr; + + } else { + conffile.invalidValueException(entry); + } + } + + if((entry = gource_settings->getEntry("output-stop-date")) != 0) { + + if(!entry->hasValue()) conffile.entryException(entry, "specify output-stop-date (YYYY-MM-DD hh:mm:ss)"); + + std::string output_stop_date_string = entry->getString(); + + if(parseDateTime(output_stop_date_string, output_stop_timestamp)) { + + struct tm * timeinfo; + timeinfo = localtime ( &output_stop_timestamp ); + + time_t output_stop_timestamp_rounded = output_stop_timestamp; + + if(timeinfo->tm_hour > 0 || timeinfo->tm_min > 0 || timeinfo->tm_sec > 0) { + output_stop_timestamp_rounded += 60*60*24; + } + + char datestr[256]; + strftime(datestr, 256, "%Y-%m-%d", localtime ( &output_stop_timestamp_rounded )); + output_stop_date = datestr; + + } else { + conffile.invalidValueException(entry); + } + } + if((entry = gource_settings->getEntry("start-position")) != 0) { if(!entry->hasValue()) conffile.entryException(entry, "specify start-position (float,random)"); diff --git a/src/gource_settings.h b/src/gource_settings.h index 1975ec59..9550271f 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -61,6 +61,11 @@ class GourceSettings : public SDLAppSettings { time_t start_timestamp; time_t stop_timestamp; + std::string output_start_date; + std::string output_stop_date; + time_t output_start_timestamp; + time_t output_stop_timestamp; + float start_position; float stop_position; float stop_at_time; From 29071c77bc3471115564d8960b4358c0190bd607 Mon Sep 17 00:00:00 2001 From: Tamas Kalman Date: Fri, 26 Dec 2025 01:01:24 -0800 Subject: [PATCH 2/2] Add documentation for --output-start-date and --output-stop-date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the new segment rendering options in README.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index b1e5c2ec..3c43116c 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,26 @@ options: Uses the same format as --start-date. + --output-start-date "YYYY-MM-DD hh:mm:ss +tz" + Start outputting frames from this date. + + Unlike --start-date which filters log entries, this option simulates + the full repository history but only outputs frames from the specified + date onwards. Files and users will be in their correct positions as if + the entire history had been rendered. + + Uses the same format as --start-date. + + --output-stop-date "YYYY-MM-DD hh:mm:ss +tz" + Stop outputting frames after this date. + + Unlike --stop-date which filters log entries, this option simulates + the full repository history but stops outputting frames after the + specified date. Useful for rendering segments of long repository + histories without processing the entire history multiple times. + + Uses the same format as --start-date. + -p, --start-position POSITION Begin at some position in the log (between 0.0 and 1.0 or 'random').