예제 #1
0
/**
 * Initialize platform level services.
 *
 * \note This must be called from the main thread due to issues with the devices
 * we use via the WINAPI, MCI (cdaudio, mixer etc) on the WIN32 platform.
 */
void Sys_Init(void)
{
    uint startTime;

    Con_Message("Setting up platform state...");

    startTime = (verbose >= 2? Timer_RealMilliseconds() : 0);

    VERBOSE( Con_Message("Initializing Audio subsystem...") )
    S_Init();

#ifdef DENG_CATCH_SIGNALS
    // Register handler for abnormal situations (in release build).
    signal(SIGSEGV, handler);
    signal(SIGTERM, handler);
    signal(SIGILL, handler);
    signal(SIGFPE, handler);
    signal(SIGILL, handler);
    signal(SIGABRT, handler);
#endif

#ifndef WIN32
    // We are not worried about broken pipes. When a TCP connection closes,
    // we prefer to receive an error code instead of a signal.
    signal(SIGPIPE, SIG_IGN);
#endif

    VERBOSE( Con_Message("Initializing Network subsystem...") )
    N_Init();

    VERBOSE2( Con_Message("Sys_Init: Completed in %.2f seconds.", (Timer_RealMilliseconds() - startTime) / 1000.0f) );
}
예제 #2
0
/*
 * Remove stopped logical sounds from the hash.
 */
void Sfx_PurgeLogical(void)
{
    static uint lastTime = 0;
    uint    i, nowTime = Timer_RealMilliseconds();
    logicsound_t *it, *next;

    if(nowTime - lastTime < PURGE_INTERVAL)
    {
        // It's too early.
        return;
    }
    lastTime = nowTime;

    // Check all sounds in the hash.
    for(i = 0; i < LOGIC_HASH_SIZE; i++)
    {
        for(it = logicHash[i].first; it; it = next)
        {
            next = it->next;
            /*#ifdef _DEBUG
               Con_Printf("LS:%i orig=%i(%p) %s\n",
               it->id, it->origin? it->origin->thinker.id : 0,
               it->origin, it->isRepeating? "[repeat]" : "");
               #endif */
            if(!it->isRepeating && it->endTime < nowTime)
            {
                // This has stopped.
                Sfx_DestroyLogical(it);
            }
        }
    }
}
예제 #3
0
void Sys_BlockUntilRealTime(uint realTimeMs)
{
    uint remaining = realTimeMs - Timer_RealMilliseconds();
    if(remaining > 50)
    {
        // Target time is in the past; or the caller is attempting to wait for
        // too long a time.
        return;
    }

    while(Timer_RealMilliseconds() < realTimeMs)
    {
        // Do nothing; don't yield execution. We want to exit here at the
        // precise right moment.
    }
}
예제 #4
0
void DD_WaitForOptimalUpdateTime(void)
{
    // All times are in milliseconds.
    static uint prevUpdateTime = 0;
    uint nowTime, elapsed = 0;
    uint targetUpdateTime;

    // optimalDelta is integer on purpose: we're measuring time at a 1 ms
    // accuracy, so we can't use fractions of a millisecond.
    const uint optimalDelta = (maxFrameRate > 0? 1000/maxFrameRate : 1);

    if(Sys_IsShuttingDown()) return; // No need for finesse.

    // This is when we would ideally like to make the update.
    targetUpdateTime = prevUpdateTime + optimalDelta;

    // Check the current time.
    nowTime = Timer_RealMilliseconds();
    elapsed = nowTime - prevUpdateTime;

    if(elapsed < optimalDelta)
    {
        uint needSleepMs = optimalDelta - elapsed;

        // We need to wait until the optimal time has passed.
        if(needSleepMs > 5)
        {
            // Longer sleep, yield to other threads.
            Sys_Sleep(needSleepMs - 3); // Leave some room for inaccuracies.
        }

        // Attempt to make sure we really wait until the optimal time.
        Sys_BlockUntilRealTime(targetUpdateTime);

        nowTime = Timer_RealMilliseconds();
        elapsed = nowTime - prevUpdateTime;
    }

    // The time for this update.
    prevUpdateTime = nowTime;

    timeDeltaStatistics((int)elapsed - (int)optimalDelta);
}
예제 #5
0
/**
 * Buffer streamer. Called by the Sfx refresh thread.
 * @param buf  Sound buffer.
 */
void DS_Dummy_SFX_Refresh(sfxbuffer_t* buf)
{
    // Can only be done if there is a sample and the buffer is playing.
    if(!buf || !buf->sample || !(buf->flags & SFXBF_PLAYING))
        return;

    // Have we passed the predicted end of sample?
    if(!(buf->flags & SFXBF_REPEAT) && Timer_RealMilliseconds() >= buf->endTime)
    {
        // Time for the sound to stop.
        DS_Dummy_SFX_Stop(buf);
    }
}
예제 #6
0
void Net_SendPing(int player, int count)
{
    client_t           *cl = clients + player;

    // Valid destination?
    if((player == consolePlayer) || (isClient && player))
        return;

    if(count)
    {
        // We can't start a new ping run until the old one is done.
        if(cl->ping.sent)
            return;

        // Start a new ping session.
        if(count > MAX_PINGS)
            count = MAX_PINGS;
        cl->ping.current = 0;
        cl->ping.total = count;
    }
    else
    {
        // Continue or finish the current pinger.
        if(++cl->ping.current >= cl->ping.total)
        {
            // We're done.
            cl->ping.sent = 0;
            // Print a summary (average ping, loss %).
            Net_ShowPingSummary(netBuffer.player);
            return;
        }
    }

    // Send a new ping.
    Msg_Begin(PKT_PING);
    cl->ping.sent = Timer_RealMilliseconds();
    Writer_WriteUInt32(msgWriter, cl->ping.sent);
    Msg_End();

    // Update the length of the message.
    netBuffer.player = player;
    N_SendPacket(10000);
}
예제 #7
0
void DS_Dummy_SFX_Play(sfxbuffer_t* buf)
{
    // Playing is quite impossible without a sample.
    if(!buf || !buf->sample)
        return;

    // Do we need to reload?
    if(buf->flags & SFXBF_RELOAD)
        DS_Dummy_SFX_Load(buf, buf->sample);

    // The sound starts playing now?
    if(!(buf->flags & SFXBF_PLAYING))
    {
        // Calculate the end time (milliseconds).
        buf->endTime = Timer_RealMilliseconds() + DS_DummyBufferLength(buf);
    }

    // The buffer is now playing.
    buf->flags |= SFXBF_PLAYING;
}
예제 #8
0
/*
 * Returns true if the sound is currently playing somewhere in the world.
 * It doesn't matter if it's audible or not.
 *
 * id=0: true if any sounds are playing using the specified origin
 */
boolean Sfx_IsPlaying(int id, mobj_t *origin)
{
    uint    nowTime = Timer_RealMilliseconds();
    logicsound_t *it;
    int     i;

    if(id)
    {
        for(it = Sfx_LogicHash(id)->first; it; it = it->next)
        {
            if(it->id == id && it->origin == origin &&
               (it->endTime > nowTime || it->isRepeating))
            {
                // This one is still playing.
                return true;
            }
        }
    }
    else if(origin)
    {
        // Check if the origin is playing any sound.
        for(i = 0; i < LOGIC_HASH_SIZE; i++)
        {
            for(it = logicHash[i].first; it; it = it->next)
            {
                if(it->origin == origin &&
                   (it->endTime > nowTime || it->isRepeating))
                {
                    // This one is playing.
                    return true;
                }
            }
        }
    }

    // The sound was not found.
    return false;
}
예제 #9
0
// Called when a ping packet comes in.
void Net_PingResponse(void)
{
    client_t* cl = &clients[netBuffer.player];
    int time = Reader_ReadUInt32(msgReader);

    // Is this a response to our ping?
    if(time == cl->ping.sent)
    {
        // Record the time and send the next ping.
        cl->ping.times[cl->ping.current] =
            (Timer_RealMilliseconds() - time) / 1000.0f;
        // Show a notification.
        /*Con_Printf( "Ping to plr %i: %.0f ms.\n", netbuffer.player,
           cl->ping.times[cl->ping.current] * 1000); */
        // Send the next ping.
        Net_SendPing(netBuffer.player, 0);
    }
    else
    {
        // Not ours, just respond.
        Net_SendBuffer(netBuffer.player, 10000);
    }
}
예제 #10
0
/*
 * The sound is entered into the list of playing sounds. Called when a
 * 'world class' sound is started, regardless of whether it's actually
 * started on the local system.
 */
void Sfx_StartLogical(int id, mobj_t *origin, boolean isRepeating)
{
    logicsound_t *node;
    uint length = (isRepeating ? 1 : Sfx_GetSoundLength(id));

    if(!length)
    {
        // This is not a valid sound.
        return;
    }

    if(origin && sfxOneSoundPerEmitter)
    {
        // Stop all previous sounds from this origin (only one per origin).
        Sfx_StopLogical(0, origin);
    }

    id &= ~DDSF_FLAG_MASK;
    node = Sfx_CreateLogical(id);
    node->origin = origin;
    node->isRepeating = isRepeating;
    node->endTime = Timer_RealMilliseconds() + length;
}