Example #1
0
int main(int argc, char *argv[]) {

    //defaults
    int   width       = 1024;
    int   height      = 768;
    bool  fullscreen  = false;

    float simu_speed  = 1.0f;
    float update_rate = 5.0f;
    float time_scale = 1.0f;
    bool multisample  = false;

    vec3f background = vec3f(0.0, 0.0, 0.0);

    int video_framerate = 60;
    std::string ppm_file_name;

    std::string mpeg_file_name;

    std::string logfile = "";

    std::vector<std::string> groupstr;

    std::vector<std::string> arguments;

    XInitThreads();
    SDLAppInit("Logstalgia", "logstalgia");

    SDLAppParseArgs(argc, argv, &width, &height, &fullscreen, &arguments);

    for (int i=0; i<arguments.size(); i++) {

        std::string args = arguments[i];

        if(args == "-h" || args == "-?" || args == "--help") {
            logstalgia_help();
        }

        if(args == "-c") {
            gSplash = 15.0f;
            continue;
        }

        if(args == "-x" || args == "--full-hostnames") {
            gMask = false;
            continue;
        }

        if(args == "--hide-url-prefix") {
            gHideURLPrefix = true;
            continue;
        }

        if(args == "-s" || args == "--speed") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify speed (1 to 30)");
            }

            simu_speed = atof(arguments[++i].c_str());

            if(simu_speed < 1.0f || simu_speed > 30.0f) {
                logstalgia_quit("speed should be between 1 and 30\n");
            }

            continue;
        }

        if(args == "-t" || args == "--time-scale") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify time scale (0.25 to 4)");
            }

            time_scale = atof(arguments[++i].c_str());

            if(time_scale < 0.25f || time_scale > 4.0f) {
                logstalgia_quit("time scale should be between 0.25 and 4\n");
            }

            continue;
        }

        if(args == "-u" || args == "--update-rate") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify update rate (1 to 60)");
            }

            update_rate = atof(arguments[++i].c_str());

            if(update_rate < 1.0f || update_rate > 60.0f) {
                logstalgia_quit("update rate should be between 1 and 60\n");
            }

            continue;
        }

        //specify page url group
        if(args == "-g") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify group definition");
            }

            groupstr.push_back(arguments[++i].c_str());

            continue;
        }

        if(args == "--paddle-mode") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify paddle-mode (vhost,pid)");
            }

            std::string paddle_mode = arguments[++i];

            if(paddle_mode == "single") {
                gPaddleMode = PADDLE_SINGLE;

            } else if(paddle_mode == "pid") {
                gPaddleMode = PADDLE_PID;

            } else if(paddle_mode == "vhost") {
                gPaddleMode = PADDLE_VHOST;

            } else {
                logstalgia_quit("invalid paddle-mode");

            }

            continue;
        }

        if(args == "--paddle-position") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify paddle-position (0.25 - 0.75)");
            }

            gPaddlePosition = atof(arguments[++i].c_str());

            if(gPaddlePosition < 0.25f || gPaddlePosition > 0.75f) {
                logstalgia_quit("paddle-position outside of range 0.25 - 0.75");
            }

            continue;
        }

        if(args == "--font-size") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify font-size (10 - 40)");
            }

            gFontSize = atoi(arguments[++i].c_str());

            if(gFontSize < 10 || gFontSize > 40) {
                logstalgia_quit("font-size outside of range 10 - 40");
            }

            continue;
        }

        if(args == "-b" || args == "--background") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify background colour (FFFFFF)");
            }

            int r,g,b;
            std::string colstring = arguments[++i];

            if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
                background = vec3f(r,g,b);
                background /= 255.0f;
            } else {
                logstalgia_quit("invalid colour string");
            }

            continue;

        }

        //dont bounce
        if(args == "--no-bounce") {
            gBounce = false;
            continue;
        }

        //dont draw response code
        if(args == "--hide-response-code") {
            gResponseCode = false;
            continue;
        }

        //no paddle
        if(args == "--hide-paddle") {
            gPaddleMode = PADDLE_NONE;
            continue;
        }

        if(args == "--start-position") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify start-position (0.0 - 1.0)");
            }

            gStartPosition = atof(arguments[++i].c_str());

            if(gStartPosition<=0.0 || gStartPosition>=1.0) {
                logstalgia_quit("start-position outside of range 0.0 - 1.0 (non-inclusive)");
            }

            continue;
        }

        if(args == "--stop-position") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify stop-position (0.0 - 1.0)");
            }

            gStopPosition = atof(arguments[++i].c_str());

            if(gStopPosition<=0.0 || gStopPosition>1.0) {
                logstalgia_quit("stop-position outside of range 0.0 - 1.0");
            }

            continue;
        }

        //disable automatic skipping of empty time periods
        if(args == "--disable-auto-skip") {
            gAutoSkip = false;
            continue;
        }

        //disable progress bar
        if(args == "--disable-progress") {
            gDisableProgress = true;
            continue;
        }

        if(args == "--disable-glow") {
            gDisableGlow = true;
            continue;
        }

        //enable multisampling
        if(args == "--multi-sampling") {
            multisample = true;
            continue;
        }

        if(args == "--glow-duration") {
            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify glow-duration (float)");
            }

            gGlowDuration = atof(arguments[++i].c_str());

            if(gGlowDuration<=0.0 || gGlowDuration>1.0) {
                logstalgia_quit("glow-duration outside of range 0.0 - 1.0");
            }

            continue;
        }

        if(args == "--glow-intensity") {
            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify glow-intensity (float)");
            }

            gGlowIntensity = atof(arguments[++i].c_str());

            if(gGlowIntensity<=0.0) {
                logstalgia_quit("invalid glow-intensity value");
            }

            continue;
        }

        if(args == "--glow-multiplier") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify glow-multiplier (float)");
            }

            gGlowMultiplier = atof(arguments[++i].c_str());

            if(gGlowMultiplier<=0.0) {
                logstalgia_quit("invalid glow-multiplier value");
            }

            continue;
        }

        if(args == "--output-ppm-stream") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify ppm output file or '-' for stdout");
            }

            ppm_file_name = arguments[++i];

#ifdef _WIN32
            if(ppm_file_name == "-") {
                logstalgia_quit("stdout PPM mode not supported on Windows");
            }
#endif

            continue;
        }

        if(args == "--output-mpeg-stream") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify mpeg output file or '-' for stdout");
            }

            mpeg_file_name = arguments[++i];

#ifdef _WIN32
            if(mpeg_file_name == "-") {
                logstalgia_quit("stdout MPEG mode not supported on Windows");
            }
#endif

            continue;
        }

        if(args == "--output-framerate") {

            if((i+1)>=arguments.size()) {
                logstalgia_quit("specify framerate (25,30,60)");
            }

            video_framerate = atoi(arguments[++i].c_str());

            if(   video_framerate != 25
               && video_framerate != 30
               && video_framerate != 60) {
                logstalgia_quit("supported framerates are 25,30,60");
            }

            continue;
        }

        if(args == "--sync") {
            gSyncLog = true;
            if(!logfile.size()) logfile = "-";
            continue;
        }

        //if given a non option arg treat it as a file, or if it is '-', pass that too (stdin)
        if(args == "-" || args.size() >= 1 && args[0] != '-') {
            logfile = args;
            continue;
        }

        // unknown argument
        std::string arg_error = std::string("unknown option ") + std::string(args);

        logstalgia_quit(arg_error);
    }

#ifdef _WIN32
    if(!logfile.size()) {
        //open file dialog
        logfile = win32LogSelector();

        if(!logfile.size()) return 0;
    }
#endif

    if(!logfile.size()) logstalgia_quit("no file supplied");

    // wait for a character on the file handle if reading stdin
    if(logfile == "-") {

#ifdef _WIN32
        DWORD available_bytes;
        HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

        while(PeekNamedPipe(stdin_handle, 0, 0, 0,
            &available_bytes, 0) && available_bytes==0 && !std::cin.fail()) {
            SDL_Delay(100);
        }
#else
        while(std::cin.peek() == EOF && !std::cin.fail()) SDL_Delay(100);
#endif
        std::cin.clear();
    }

    //enable vsync
    display.enableVsync(true);

    // this causes corruption on some video drivers
    if(multisample) display.multiSample(4);

    display.init("Logstalgia", width, height, fullscreen);

    //init frame exporter
    FrameExporter* exporter = 0;

    if(ppm_file_name.size() > 0) {

        try {

            exporter = new PPMExporter(ppm_file_name);

        } catch(PPMExporterException& exception) {

            char errormsg[1024];
            snprintf(errormsg, 1024, "could not write to '%s'", exception.what());

            logstalgia_quit(errormsg);
        }
    }else if(mpeg_file_name.size() > 0) {

        try {

            exporter = new MPEGExporter(mpeg_file_name);

        } catch(MPEGExporterException& exception) {

            char errormsg[1024];
            snprintf(errormsg, 1024, "could not write to '%s'", exception.what());

            logstalgia_quit(errormsg);
        }
    }

    if(multisample) glEnable(GL_MULTISAMPLE_ARB);

    Logstalgia* ls = 0;

    try {
        ls = new Logstalgia(logfile, simu_speed, update_rate, time_scale);

        //init frame exporter
        if(ppm_file_name.size() > 0 || mpeg_file_name.size() > 0) {
            ls->setFrameExporter(exporter, video_framerate);
        }

        for(size_t i=0;i<groupstr.size();i++) {
            ls->addGroup(groupstr[i]);
        }

        ls->setBackground(background);

        ls->run();

    } catch(ResourceException& exception) {

        char errormsg[1024];
        snprintf(errormsg, 1024, "failed to load resource '%s'", exception.what());

        logstalgia_quit(errormsg);

    } catch(SDLAppException& exception) {

        if(exception.showHelp()) {
            logstalgia_help();
        } else {
            logstalgia_quit(exception.what());
        }

    }

    if(ls!=0) delete ls;

    if(exporter!=0) delete exporter;

    display.quit();

    return 0;
}
Example #2
0
int main(int argc, char *argv[]) {

    int width  = 1024;
    int height = 768;
    bool fullscreen=false;
    bool multisample=false;
    vec3f background = vec3f(0.1, 0.1, 0.1);

    int video_framerate = 60;
    std::string ppm_file_name;

    std::vector<std::string> follow_users;
    std::vector<std::string> highlight_users;
    std::vector<Regex*> filters;

    float start_position = 0.0;
    float stop_position  = 0.0;
    bool stop_on_idle = false;

    std::string logfile = ".";

    std::vector<std::string> arguments;

    SDLAppParseArgs(argc, argv, &width, &height, &fullscreen, &arguments);

    for(int i=0;i<arguments.size();i++) {
        std::string args = arguments[i];

        if(args == "-h" || args == "-?" || args == "--help") {
            gource_help("");
        }

        if(args == "--loop") {
            gGourceFileLoop = true;
            continue;
        }

        if(args == "--git-branch") {

            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify a git branch");
            }

            gGourceGitLogCommand += " ";
            gGourceGitLogCommand += arguments[++i];

            continue;
        }

        if(args == "--git-log-command") {
                gource_info(gGourceGitLogCommand);
        }

        if(args == "--cvs-exp-command") {
                gource_info(gGourceCvsExpLogCommand);
        }

        if(args == "--hg-log-command") {
                std::string command = gGourceMercurialCommand();

                gource_info(command);
        }


        if(args == "--date-format") {

            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify a date format string");
            }

            gGourceDateFormat = arguments[++i];

            continue;
        }

        if(args == "--hide-date") {
            gGourceHideDate = true;
            continue;
        }

        if(args == "--disable-auto-skip") {
            gGourceAutoSkipSeconds = -1.0;
            continue;
        }

        if(args == "--disable-progress") {
            gGourceDisableProgress = true;
            continue;
        }

        if(args == "--disable-bloom") {
            gGourceDisableBloom = true;
            continue;
        }

        if(args == "--hide-users") {
            gGourceHideUsers = true;
            continue;
        }

        if(args == "--hide-tree") {
            gGourceHideTree = true;
            continue;
        }

        if(args == "--hide-files") {
            gGourceHideFiles = true;
            continue;
        }

        if(args == "--hide-usernames") {
            gGourceHideUsernames = true;
            continue;
        }

        if(args == "--hide-filenames") {
            gGourceHideFilenames = true;
            continue;
        }

        if(args == "--hide-dirnames") {
            gGourceDrawDirName = false;
            continue;
        }

        if(args == "--multi-sampling") {
            multisample = true;
            continue;
        }

        if(args == "--colour-images") {
            gGourceColourUserImages = true;
            continue;
        }

        if(args == "--crop") {
            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify crop (vertical,horizontal)");
            }

            std::string crop = arguments[++i];

            if(crop == "vertical") {
                gGourceVerticalCrop = true;
            } else if (crop == "horizontal") {
                gGourceHorizontalCrop = true;
            } else {
                gource_help("invalid crop value");
            }

            continue;
        }

        if(args == "--log-format") {
            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify log-format (format)");
            }

            gGourceLogFormat = arguments[++i];

            if(   gGourceLogFormat != "git"
               && gGourceLogFormat != "cvs"
               && gGourceLogFormat != "custom"
               && gGourceLogFormat != "apache") {
                gource_help("unknown log-format");
            }

            continue;

        }

        if(args == "--default-user-image") {

            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify default-user-image (image path)");
            }

            gGourceDefaultUserImage = arguments[++i];

            continue;
        }

        if(args == "--user-image-dir") {

            if((i+1)>=arguments.size() || arguments[i+1].size() == 0) {
                gource_help("specify user-image-dir (directory)");
            }

            gGourceUserImageDir = arguments[++i];

            //append slash
            if(gGourceUserImageDir[gGourceUserImageDir.size()-1] != '/') {
                gGourceUserImageDir += std::string("/");
            }

            continue;
        }

        if(args == "--bloom-intensity") {
            if((i+1)>=arguments.size()) {
                gource_help("specify bloom-intensity (float)");
            }

            gGourceBloomIntensity = atof(arguments[++i].c_str());

            if(gGourceBloomIntensity<=0.0) {
                gource_help("invalid bloom-intensity value");
            }

            continue;
        }

        if(args == "--bloom-multiplier") {

            if((i+1)>=arguments.size()) {
                gource_help("specify bloom-multiplier (float)");
            }

            gGourceBloomMultiplier = atof(arguments[++i].c_str());

            if(gGourceBloomMultiplier<=0.0) {
                gource_help("invalid bloom-multiplier value");
            }

            continue;
        }

        if(args == "-e" || args == "--elasticity") {

            if((i+1)>=arguments.size()) {
                gource_help("specify elasticity (float)");
            }

            gGourceElasticity = atof(arguments[++i].c_str());

            if(gGourceElasticity<=0.0) {
                gource_help("invalid elasticity value");
            }

            continue;
        }

        if(args == "-b" || args == "--background") {

            if((i+1)>=arguments.size()) {
                gource_help("specify background colour (#FFFFFF)");
            }

            int r,g,b;
            std::string colstring = arguments[++i];

            if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
                background = vec3f(r,g,b);
                background /= 255.0f;
            } else {
                gource_help("invalid colour string");
            }

            continue;
        }

        if(args == "-s" || args == "--seconds-per-day") {

            if((i+1)>=arguments.size()) {
                gource_help("specify seconds-per-day (seconds)");
            }

            gGourceDaysPerSecond = atof(arguments[++i].c_str());

            if(gGourceDaysPerSecond<=0.0) {
                gource_help("invalid seconds-per-day value");
            }

            gGourceDaysPerSecond = 1.0 / gGourceDaysPerSecond;

            continue;
        }

        if(args == "--realtime") {
            gGourceDaysPerSecond = 1.0 / 86400.0;

            continue;
        }

        if(args == "-a" || args == "--auto-skip-seconds") {

            if((i+1)>=arguments.size()) {
                gource_help("specify auto-skip-seconds");
            }

            gGourceAutoSkipSeconds = (float) atof(arguments[++i].c_str());

            if(gGourceAutoSkipSeconds <= 0.0) {
                gource_help("invalid auto-skip-seconds value");
            }

            continue;
        }

        if(args == "-i" || args == "--file-idle-time") {

            if((i+1)>=arguments.size()) {
                gource_help("specify file-idle-time (seconds)");
            }

            gGourceMaxFileIdle = (float) atoi(arguments[++i].c_str());

            if(gGourceMaxFileIdle<1.0) {
                gource_help("invalid file-idle-time value");
            }

            continue;
        }

        if(args == "-p" || args == "--start-position") {

            if((i+1)>=arguments.size()) {
                gource_help("specify start-position (float)");
            }

            start_position = atof(arguments[++i].c_str());

            if(start_position<=0.0 || start_position>=1.0) {
                gource_help("start-position outside of range 0.0 - 1.0 (non-inclusive)");
            }

            continue;
        }

        if(args == "--stop-position") {

            if((i+1)>=arguments.size()) {
                gource_help("specify stop-position (float)");
            }

            stop_position = atof(arguments[++i].c_str());

            if(stop_position<=0.0 || stop_position>1.0) {
                gource_help("stop-position outside of range 0.0 - 1.0 (inclusive)");
            }

            continue;
        }

        if(args == "--stop-on-idle") {

            stop_on_idle = true;

            continue;
        }

        if(args == "--max-files") {

            if((i+1)>=arguments.size()) {
                gource_help("specify max-files (number)");
            }

            gGourceMaxFiles = atoi(arguments[++i].c_str());

            if(gGourceMaxFiles<1) {
                gource_help("invalid max-files value");
            }

            continue;
        }

        if(args == "--max-file-lag") {

            if((i+1)>=arguments.size()) {
                gource_help("specify max-file-lag (seconds)");
            }

            gGourceMaxFileLagSeconds = atof(arguments[++i].c_str());

            if(gGourceMaxFileLagSeconds==0.0) {
                gource_help("invalid max-file-lag value");
            }

            continue;
        }

        if(args == "--user-friction") {

            if((i+1)>=arguments.size()) {
                gource_help("specify user-friction (seconds)");
            }

            gGourceUserFriction = atof(arguments[++i].c_str());

            if(gGourceUserFriction<=0.0) {
                gource_help("invalid user-friction value");
            }

            gGourceUserFriction = 1.0 / gGourceUserFriction;

            continue;
        }

        if(args == "--user-scale") {

            if((i+1)>=arguments.size()) {
                gource_help("specify user-scale (scale)");
            }

            gGourceUserScale = atof(arguments[++i].c_str());

            if(gGourceUserScale<=0.0 || gGourceUserScale>100.0) {
                gource_help("invalid user-scale value");
            }

            continue;
        }


        if(args == "--max-user-speed") {

            if((i+1)>=arguments.size()) {
                gource_help("specify max-user-speed (units)");
            }

            gGourceMaxUserSpeed = atof(arguments[++i].c_str());

            if(gGourceMaxUserSpeed<=0) {
                gource_help("invalid max-user-speed value");
            }

            continue;
        }

        if(args == "--highlight-all-users") {

            gGourceHighlightAllUsers = true;

            continue;
        }

        if(args == "--highlight-user") {

            if((i+1)>=arguments.size()) {
                gource_help("specify highlight-user (user)");
            }

            highlight_users.push_back(arguments[++i]);

            continue;
        }

        if(args == "--follow-user") {

            if((i+1)>=arguments.size()) {
                gource_help("specify follow-user (user)");
            }

            follow_users.push_back(arguments[++i]);

            continue;
        }

        if(args == "--file-filter") {

            if((i+1)>=arguments.size()) {
                gource_help("specify file-filter (regex)");
            }

            std::string filter_string = arguments[++i];

            Regex* r = new Regex(filter_string, 1);

            if(!r->isValid()) {
                delete r;
                gource_help("invalid filt-filter regular expression");
            }

            filters.push_back(r);

            continue;
        }

        if(args == "--output-ppm-stream") {

            if((i+1)>=arguments.size()) {
                gource_help("specify ppm output file or '-' for stdout");
            }

            ppm_file_name = arguments[++i];

#ifdef _WIN32
            if(ppm_file_name == "-") {
                gource_help("stdout PPM mode not supported on Windows");
            }
#endif

            continue;
        }

        if(args == "--output-framerate") {

            if((i+1)>=arguments.size()) {
                gource_help("specify framerate (25,30,60)");
            }

            video_framerate = atoi(arguments[++i].c_str());

            if(   video_framerate != 25
               && video_framerate != 30
               && video_framerate != 60) {
                gource_help("supported framerates are 25,30,60");
            }

            continue;
        }

        // assume this is the log file
        if(args == "-" || args.size() >= 1 && args[0] != '-') {
            logfile = args;
            continue;
        }

        // unknown argument
        std::string arg_error = std::string("unknown option ") + std::string(args);

        gource_help(arg_error);
    }

    // wait for a character on the file handle if reading stdin
    if(logfile == "-") {

        if(gGourceLogFormat.size() == 0) {
            gource_help("--log-format required when reading from STDIN");
        }

        while(std::cin.peek() == EOF && !std::cin.fail()) SDL_Delay(100);
        std::cin.clear();
    }

    //remove trailing slash and check if logfile is a directory
    if(logfile.size() &&
       (logfile[logfile.size()-1] == '\\' || logfile[logfile.size()-1] == '/')) {
        logfile = logfile.substr(0,logfile.size()-1);
    }

#ifdef _WIN32
    bool isdir = false;

    //on windows, pre-open console window if we think this is a directory the
    //user is trying to open, as system() commands will create a console window
    //if there isn't one anyway.

    if(logfile.size()>0) {
        struct stat fileinfo;
        int rc = stat(logfile.c_str(), &fileinfo);

        if(rc==0 && fileinfo.st_mode & S_IFDIR) isdir = true;
    }

    if(logfile.size()==0 || isdir) {
        createWindowsConsole();
    }
#endif

    // this causes corruption on some video drivers
    if(multisample) {
        display.multiSample(4);
    }

    //init frame exporter
    FrameExporter* exporter = 0;

    if(ppm_file_name.size() > 0) {
        exporter = new PPMExporter(ppm_file_name);
    }

    //enable vsync
    display.enableVsync(true);

    display.init("Gource", width, height, fullscreen);

    if(multisample) glEnable(GL_MULTISAMPLE_ARB);

    Gource* gource = new Gource(logfile);

    if(start_position>0.0) gource->setStartPosition(start_position);
    if(stop_position>0.0)  gource->setStopPosition(stop_position);

    gource->setStopOnIdle(stop_on_idle);

    if(exporter!=0) gource->setFrameExporter(exporter, video_framerate);

    gource->setBackground(background);

    for(std::vector<std::string>::iterator it = follow_users.begin(); it != follow_users.end(); it++) {
        gource->addFollowUser(*it);
    }

    for(std::vector<std::string>::iterator it = highlight_users.begin(); it != highlight_users.end(); it++) {
        gource->addHighlightUser(*it);
    }

    for(std::vector<Regex*>::iterator it = filters.begin(); it != filters.end(); it++) {
        gource->addFilter(*it);
    }

    gource->run();

    delete gource;

    if(exporter != 0) delete exporter;

    //free resources
    display.quit();

    return 0;
}