예제 #1
0
파일: fb.cpp 프로젝트: ascendancy721/gnash
bool
FBGui::run()
{
//  GNASH_REPORT_FUNCTION;

#ifdef USE_TSLIB
    int ts_loop_count = 0;
#endif

    VirtualClock& timer = getClock();
    int delay = 0;
    
    // let the GUI recompute the x/y scale factors to best fit the whole screen
    resize_view(_validbounds.width(), _validbounds.height());

    float fps = getFPS();
    
    // FIXME: this value is arbitrary, and will make any movie with
    // less than 12 frames eat up more of the cpu. It should probably
    // be a much lower value, like 2.
    if (fps > 12) {
        delay = static_cast<int>(100000/fps);
    } else {
        // 10ms per heart beat
        delay = 10000;
    }
    // log_debug(_("Movie Frame Rate is %d, adjusting delay to %dms"), fps,
    //           _interval * delay);
    
    // This loops endlessly at the frame rate
    while (!terminate_request) {  
        // wait the "heartbeat" inteval. _interval is in milliseconds,
        // but gnashSleep() wants nanoseconds, so adjust by 1000.
        gnashSleep(_interval * 1000);
        // TODO: Do we need to check the real time slept or is it OK when we woke
        // up early because of some Linux signal sent to our process (and thus
        // "advance" faster than the "heartbeat" interval)? - Udo

#ifdef USE_TSLIB
        ts_loop_count++; //increase loopcount
#endif
        
        // check input devices
        checkForData();

        // advance movie  
        Gui::advance_movie(this);

        // check if we've reached a timeout
        if (_timeout && timer.elapsed() >= _timeout ) {
            break;
        }
    }

    return true;
}
예제 #2
0
void
SDL_sound_handler::initAudio()
{
    // NOTE: we open and close the audio card for the sole purpose
    //       of throwing an exception on error (unavailable audio
    //       card). Normally we'd want to open the audio card only
    //       when needed (it has a cost in number of wakeups).
    openAudio();

#ifdef WIN32
    // SDL can hang on windows if SDL_CloseAudio() is called immediately
    // after SDL_OpenAudio(). It's evidently to do with threading, but
    // internal to SDL. This is a tacky solution, but it's only windows.
    gnashSleep(1);
#endif

    closeAudio();

}
예제 #3
0
bool
MouseDevice::command(unsigned char cmd, unsigned char *buf, int count)
{
    // GNASH_REPORT_FUNCTION;

    int n;
    
    // flush input buffer
    char trash[16];
    do {
        n = ::read(_fd, trash, sizeof trash);
        if (n > 0) 
            log_debug(_("mouse_command: discarded %d bytes from input buffer"), n);
    } while (n > 0);
    
    // send command
    if ( -1 == ::write(_fd, &cmd, 1) ) {
        return false;
    }

    // read response (if any)
    while (count > 0) {
        gnashSleep(250*1000); // 250 ms inter-char timeout (simple method)
        // TODO: use select() instead
        
        n = read(_fd, buf, count);
        if (n <= 0) {
            return false;
        }
        count -= n;
        buf += n;
    }
    
    return true;
    
} // command()
예제 #4
0
파일: SharedMem.cpp 프로젝트: aopui/gnash
bool
SharedMem::getSemaphore()
{
#ifndef __amigaos4__
    // Struct for semctl
    union semun {
        int val;
        struct semid_ds* buf;
        unsigned short* array;
    };
#endif

    semun s;

    // We employ the textbook solution to the race condition during creation
    // and initialization of the semaphore: Create the semaphore with IPC_EXCL
    // so that for the first process, creation will succeed, but for any
    // concurrent process it will fail with EEXIST. Then, once the first
    // process is finished initializing the semaphore, semop is called (in our
    // case by calling lock()) which modifies semid_ds::otime, and the
    // concurrent process knows it can proceed with using the semaphore
    // (provided it obtains a lock.)
    _semid = ::semget(_shmkey, 1, IPC_CREAT | IPC_EXCL | 0600);
        
    if (_semid >= 0) {
        // Initialize semval.
        s.val = 1;
        int ret = ::semctl(_semid, 0, SETVAL, s);
        if (ret < 0) {
            log_error(_("Failed to set semaphore value: %1%"), strerror(errno));
            return false;
        }
        // The first semop is executed immediately after this function returns.
    } else if (errno == EEXIST) {
        _semid = semget(_shmkey, 1, 0600);
        if (_semid < 0) {
            log_error(_("Failed to obtain nonexclusive semaphore for shared "
                        "memory: %1%"), strerror(errno));
            return false;
        }

        // Wait until semid_ds::sem_otime changes.
        semid_ds buf = semid_ds();
        s.buf = &buf;
        const int maxRetries = 10;
        time_t uSecondsWait = 100; // 0.1ms
        bool ok = false;

        for(int i = 0; i < maxRetries; i++) {
            semctl(_semid, 0, IPC_STAT, s);
            if (buf.sem_otime != 0) {
                ok = true;
                break;
            } else {
                gnashSleep(uSecondsWait);
            }
        }

        if (!ok) {
            log_error(_("Timed out waiting for semaphore initialization."));
            return false;
        }
    } else {
        log_error(_("Failed creating semaphore: %1%"), strerror(errno));
        return false;
    }

    return true;
}
예제 #5
0
파일: cvm.cpp 프로젝트: diocles/gnash
// Load the named movie, make an instance, and play it, virtually.
// I.e. run through and render all the frames, even though we are not
// actually doing any output (our output handlers are disabled).
//
// What this does is warm up all the cached data in the movie, so that
// if we save that data for later, we won't have to tesselate shapes
// or build font textures again.
//
// Return the movie definition.
boost::intrusive_ptr<gnash::movie_definition>
play_movie(const std::string& filename, const RunResources& runResources)
{
    boost::intrusive_ptr<gnash::movie_definition> md;

    URL url(filename);

    try {
      if (filename == "-") {
         std::auto_ptr<IOChannel> in (
                 noseek_fd_adapter::make_stream(fileno(stdin)) );
         md = gnash::MovieFactory::makeMovie(in, filename, runResources, false);
      } else {
         if ( url.protocol() == "file" ) {
             const std::string& path = url.path();
#if 1 // add the *directory* the movie was loaded from to the local sandbox path
             size_t lastSlash = path.find_last_of('/');
             std::string dir = path.substr(0, lastSlash+1);
             rcfile.addLocalSandboxPath(dir);
             log_debug(_("%s appended to local sandboxes"), dir.c_str());
#else // add the *file* to be loaded to the local sandbox path
             rcfile.addLocalSandboxPath(path);
             log_debug(_("%s appended to local sandboxes"), path.c_str());
#endif
         }
         md = gnash::MovieFactory::makeMovie(url, runResources, NULL, false);
      }
    }
    catch (GnashException& ge) {
      md = NULL;
      fprintf(stderr, "%s\n", ge.what());
    }
    if (md == NULL) {
        std::cerr << "error: can't play movie: "<< filename << std::endl;
	    std::exit(EXIT_FAILURE);
    }

    float fps = md->get_frame_rate();
    long fpsDelay = long(1000000/fps);
    long clockAdvance = fpsDelay/1000;
    long localDelay = delay == -1 ? fpsDelay : delay; // microseconds

    log_debug("Will sleep %ld microseconds between iterations - "
            "fps is %g, clockAdvance is %lu", localDelay, fps, clockAdvance);


    // Use a clock advanced at every iteration to match exact FPS speed.
    ManualClock cl;
    gnash::movie_root m(*md, cl, runResources);
    
    // Register processor to receive ActionScript events (Mouse, Stage
    // System etc).
    m.registerEventCallback(&eventCallback);
    m.registerFSCommandCallback(&execFsCommand);

    md->completeLoad();

    m.init(md.get(), MovieClip::MovieVariables(), MovieClip::MovieVariables());
    if ( quitrequested ) { // setRootMovie would execute actions in first frame
        quitrequested = false;
        return md;
    }

    log_debug("iteration, timer: %lu, localDelay: %ld\n",
            cl.elapsed(), localDelay);
    gnashSleep(localDelay);
    
    resetLastAdvanceTimer();
    int	kick_count = 0;
    int stop_count=0;
    size_t loop_back_count=0;
    size_t latest_frame=0;
    size_t end_hitcount=0;
    size_t nadvances=0;
    // Run through the movie.
    for (;;) {
        // @@ do we also have to run through all sprite frames
        // as well?
        //
        // @@ also, ActionScript can rescale things
        // dynamically -- we can't really do much about that I
        // guess?
        //
        // @@ Maybe we should allow the user to specify some
        // safety margin on scaled shapes.
        
        size_t	last_frame = m.get_current_frame();
        //printf("advancing clock by %lu\n", clockAdvance);
        cl.advance(clockAdvance);
        m.advance();

        if ( quitrequested ) 
        {
            quitrequested = false;
            return md;
        }

        m.display(); // FIXME: for which reason are we calling display here ??
        ++nadvances;
        if ( limit_advances && nadvances >= limit_advances) {
            log_debug("exiting after %d advances", nadvances);
            break;
        }

        size_t curr_frame = m.get_current_frame();
        
        // We reached the end, done !
        if (curr_frame >= md->get_frame_count() - 1 ) {
            if ( allowed_end_hits && ++end_hitcount >= allowed_end_hits )
            {
                log_debug("exiting after %d" 
                       " times last frame was reached", end_hitcount);
                    break;
            }
        }

        // We didn't advance 
        if (curr_frame == last_frame) {
            // Max stop counts reached, kick it
            if ( secondsSinceLastAdvance() > waitforadvance ) {
                stop_count=0;

                // Kick the movie.
                if ( last_frame + 1 > md->get_frame_count() -1 ) {
                    fprintf(stderr, "Exiting after %g seconds in STOP mode at last frame\n", waitforadvance);
                    break;
                }
                fprintf(stderr, "Kicking movie after %g seconds in STOP mode, kick ct = %d\n", waitforadvance, kick_count);
                fflush(stderr);
                m.goto_frame(last_frame + 1);
                m.getRootMovie().setPlayState(gnash::MovieClip::PLAYSTATE_PLAY);
                kick_count++;

                if (kick_count > 10) {
                    printf("movie is stalled; giving up on playing it through.\n");
                    break;
                }

                    resetLastAdvanceTimer(); // It's like we advanced
            }
        }
        
        // We looped back.  Skip ahead...
        else if (m.get_current_frame() < last_frame) {
            if ( last_frame > latest_frame ) latest_frame = last_frame;
            if ( ++loop_back_count > allowloopbacks ) {
                log_debug("%d loop backs; jumping one-after "
                        "latest frame (%d)",
                        loop_back_count, latest_frame+1);
                m.goto_frame(latest_frame + 1);
                loop_back_count = 0;
            }
        } else {
            kick_count = 0;
            stop_count = 0;
            resetLastAdvanceTimer();
        }

        log_debug("iteration, timer: %lu, localDelay: %ld\n",
                cl.elapsed(), localDelay);
        gnashSleep(localDelay);
    }
 
    // Clear resources.
    MovieFactory::clear();
    
    return md;
}
예제 #6
0
bool
DumpGui::run()
{
    if ( _fileOutputFPS ) {
        _fileOutputAdvance = static_cast<int>(1000/_fileOutputFPS);
    } else {
        _fileOutputAdvance = _interval;
        _fileOutputFPS = static_cast<int>(1000/_fileOutputAdvance);
    }

    log_debug("DumpGui entering main loop with interval of %d ms", _interval);

    // heart-beat interval, in milliseconds
    // TODO: extract this value from the swf's FPS
    //       by default and allow overriding it
    //
    unsigned int clockAdvance = _interval;

    const bool doDisplay = _fileStream.is_open();

    terminate_request = false;

    _startTime = _clock.elapsed();

    while (!terminate_request) {

        _clock.advance(clockAdvance); 

        // advance movie now
        advanceMovie(doDisplay);

        if (_started) {

            writeSamples();

            // Dump a video frame if it's time for it or no frame
            // was dumped yet
            size_t elapsed = _clock.elapsed();
            if (!_framecount || 
                    (elapsed - _lastVideoFrameDump) >= _fileOutputAdvance) {
                writeFrame();
            }

            // check if we've reached a timeout
            if (_timeout && _clock.elapsed() >= _timeout) {
                break;
            }
        }

        if (_sleepUS) gnashSleep(_sleepUS);

        if (!_started && !_startTrigger.empty()) {

            // Check whether to start
            std::string path;
            std::string var;
            if (parsePath(_startTrigger, path, var)) {
                movie_root& mr = *getStage();
                const as_environment& env = mr.getRootMovie().get_environment();
                as_object* o = findObject(env, path);
                if (o) {
                    as_value val;
                    o->get_member(getURI(mr.getVM(), "_ready"), &val);
                    if (val.equals(true, 8)) {
                        log_debug("Starting dump");
                        _started = true;
                        _startTime = _clock.elapsed();
                        _lastVideoFrameDump = _startTime;
                    }
                }
            }
        }
    }

    const boost::uint32_t total_time = _clock.elapsed() - _startTime;

    std::cout << "TIME=" << total_time << std::endl;
    std::cout << "FPS_ACTUAL=" << _fileOutputFPS << std::endl;
    
    // In this Gui, quit() does not exit, but it is necessary to catch the
    // last frame for screenshots.
    quit();
    return true;
}
예제 #7
0
파일: dump.cpp 프로젝트: sunarto/gnash
bool
DumpGui::run()
{
    if ( _fileOutputFPS ) {
        _fileOutputAdvance = static_cast<int>(1000/_fileOutputFPS);
    } else {
        _fileOutputAdvance = _interval;
        _fileOutputFPS = static_cast<int>(1000/_fileOutputAdvance);
    }
    

    log_debug("DumpGui entering main loop with interval of %d ms", _interval);

    // heart-beat interval, in milliseconds
    // TODO: extract this value from the swf's FPS
    //       by default and allow overriding it
    //
    unsigned int clockAdvance = _interval;

    VirtualClock& timer = getClock();

    const bool doDisplay = _fileStream.is_open();

    _terminate_request = false;
    while (!_terminate_request) {

        _manualClock.advance(clockAdvance); 

        // advance movie now
        advanceMovie(doDisplay);

        writeSamples();

        // Dump a video frame if it's time for it or no frame
        // was dumped yet
        size_t elapsed = timer.elapsed();
        if ( ! _framecount ||
                elapsed - _lastVideoFrameDump >= _fileOutputAdvance )
        {
            writeFrame();
        }

        // check if we've reached a timeout
        if (_timeout && timer.elapsed() >= _timeout ) {
            break;
        }

        if ( _sleepUS ) gnashSleep(_sleepUS);

    }

    boost::uint32_t total_time = timer.elapsed();

    std::cout << "TIME=" << total_time << std::endl;
    std::cout << "FPS_ACTUAL=" << _fileOutputFPS << std::endl;
    
    // In this Gui, quit() does not exit, but it is necessary to catch the
    // last frame for screenshots.
    quit();
    return true;
}