Esempio n. 1
0
// Main audio processing callback.
// NOTE: Called on a separate thread from main() thread.
ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow)
{
    // Buffer size (in samples):
    long buffSize = drv.preferredSize;

    // Assume the buffer size is an even multiple of 32-bytes:
    assert((buffSize % sizeof(vec4_d64)) == 0);

    for (long i = 0; i < buffSize; ++i)
    {
        assert(index == 0 || index == 1);

        // Process 8 channels of 32-bit samples per iteration:
        for (long n = 0; n < inputChannels / 8; ++n)
        {
            const long ci = n * 8;
            const long co = drv.inputBuffers + ci;

            // Stripe input samples into a vector:
            const vec8_i32 inpSamples = _mm256_setr_epi32(
                ((long *)drv.bufferInfos[ci + 0].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 1].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 2].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 3].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 4].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 5].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 6].buffers[index])[i],
                ((long *)drv.bufferInfos[ci + 7].buffers[index])[i]
            );

            // Process audio effects:
            vec8_i32 outSamples;
            processEffects(inpSamples, outSamples, n * 2);
            // Copy outputs to output channel buffers:
            const long *outputs32 = (const long *)&outSamples;
            ((long *)drv.bufferInfos[co + 0].buffers[index])[i] = outputs32[0];
            ((long *)drv.bufferInfos[co + 1].buffers[index])[i] = outputs32[1];
            ((long *)drv.bufferInfos[co + 2].buffers[index])[i] = outputs32[2];
            ((long *)drv.bufferInfos[co + 3].buffers[index])[i] = outputs32[3];
            ((long *)drv.bufferInfos[co + 4].buffers[index])[i] = outputs32[4];
            ((long *)drv.bufferInfos[co + 5].buffers[index])[i] = outputs32[5];
            ((long *)drv.bufferInfos[co + 6].buffers[index])[i] = outputs32[6];
            ((long *)drv.bufferInfos[co + 7].buffers[index])[i] = outputs32[7];
        }
    }

    if (drv.postOutput)
        ASIOOutputReady();

    return 0L;
}
    void MageStats::recalculateDerivedStats()
    {
        clearDerivedStats();
        processEffects();

        mStrength += mStartingStrength + mBonusStrength + mSpentLevelsOnStrength;
        mMagic += mStartingMagic + mBonusMagic + mSpentLevelsOnMagic;
        mDexterity += mStartingDexterity + mBonusDexterity + mSpentLevelsOnDexterity;
        mVitality += mStartingVitality + mBonusVitality + mSpentLevelsOnVitality;
        mHP += mVitality + mBonusVitality + mLevel + 9;
        mMana += 2*mMagic + 2*mBonusMagic + 2*mLevel -2;
        mArmourClass += mDexterity/5;
        mDamageDoneBow += (mStrength * mLevel)/200;
        mDamageDoneMelee += (mStrength * mLevel)/100.0;
        mBlockingChance += mBlockingBonus;
        mBlockingChancePVP += mBlockingBonus;
        mBlockingChanceTrap += mDexterity + mBlockingBonus;
        mDamageDoneMelee += mPlayer->mInventory.getTotalAttackDamage();
        mDamageDoneBow   += mPlayer->mInventory.getTotalAttackDamage();
        mArmourClass += mPlayer->mInventory.getTotalArmourClass();
        mChanceToHitArrow += 10;
    }
Esempio n. 3
0
void AudioPort::doProcessing()
{
    if( m_mutedModel && m_mutedModel->value() )
    {
        return;
    }

    const fpp_t fpp = Engine::mixer()->framesPerPeriod();

    m_portBuffer = BufferManager::acquire(); // get buffer for processing

    Engine::mixer()->clearAudioBuffer( m_portBuffer, fpp ); // clear the audioport buffer so we can use it

    //qDebug( "Playhandles: %d", m_playHandles.size() );
    foreach( PlayHandle * ph, m_playHandles ) // now we mix all playhandle buffers into the audioport buffer
    {
        if( ph->buffer() )
        {
            if( ph->usesBuffer() )
            {
                m_bufferUsage = true;
                MixHelpers::add( m_portBuffer, ph->buffer(), fpp );
            }
            ph->releaseBuffer(); 	// gets rid of playhandle's buffer and sets
            // pointer to null, so if it doesn't get re-acquired we know to skip it next time
        }
    }

    if( m_bufferUsage )
    {
        // handle volume and panning
        // has both vol and pan models
        if( m_volumeModel && m_panningModel )
        {
            ValueBuffer * volBuf = m_volumeModel->valueBuffer();
            ValueBuffer * panBuf = m_panningModel->valueBuffer();

            // both vol and pan have s.ex.data:
            if( volBuf && panBuf )
            {
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    float v = volBuf->values()[ f ] * 0.01f;
                    float p = panBuf->values()[ f ] * 0.01f;
                    m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
                    m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
                }
            }

            // only vol has s.ex.data:
            else if( volBuf )
            {
                float p = m_panningModel->value() * 0.01f;
                float l = ( p <= 0 ? 1.0f : 1.0f - p );
                float r = ( p >= 0 ? 1.0f : 1.0f + p );
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    float v = volBuf->values()[ f ] * 0.01f;
                    m_portBuffer[f][0] *= v * l;
                    m_portBuffer[f][1] *= v * r;
                }
            }

            // only pan has s.ex.data:
            else if( panBuf )
            {
                float v = m_volumeModel->value() * 0.01f;
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    float p = panBuf->values()[ f ] * 0.01f;
                    m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
                    m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
                }
            }

            // neither has s.ex.data:
            else
            {
                float p = m_panningModel->value() * 0.01f;
                float v = m_volumeModel->value() * 0.01f;
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
                    m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
                }
            }
        }

        // has vol model only
        else if( m_volumeModel )
        {
            ValueBuffer * volBuf = m_volumeModel->valueBuffer();

            if( volBuf )
            {
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    float v = volBuf->values()[ f ] * 0.01f;
                    m_portBuffer[f][0] *= v;
                    m_portBuffer[f][1] *= v;
                }
            }
            else
            {
                float v = m_volumeModel->value() * 0.01f;
                for( f_cnt_t f = 0; f < fpp; ++f )
                {
                    m_portBuffer[f][0] *= v;
                    m_portBuffer[f][1] *= v;
                }
            }
        }
    }
    // as of now there's no situation where we only have panning model but no volume model
    // if we have neither, we don't have to do anything here - just pass the audio as is

    // handle effects
    const bool me = processEffects();
    if( me || m_bufferUsage )
    {
        Engine::fxMixer()->mixToChannel( m_portBuffer, m_nextFxChannel ); 	// send output to fx mixer
        // TODO: improve the flow here - convert to pull model
        m_bufferUsage = false;
    }

    BufferManager::release( m_portBuffer ); // release buffer, we don't need it anymore
}
Esempio n. 4
0
// Main:
int main()
{
    int retval = 0;
    bool inited = false, buffersCreated = false, started = false;
    char *error = NULL;

    drv.sampleRate = 44100.0;

    // Initialize FX parameters:
    fx.f0_gain.init();
    fx.f1_compressor.init();

    // Set our own inputs:
    for (int i = 0; i < icr; ++i)
    {
        fx.f0_gain.input.gain[i] = _mm256_set1_pd(0);   // dB

        fx.f1_compressor.input.threshold[i] = _mm256_set1_pd(-30);  // dBFS
        fx.f1_compressor.input.attack[i]    = _mm256_set1_pd(1.0);  // msec
        fx.f1_compressor.input.release[i]   = _mm256_set1_pd(80);   // msec
        fx.f1_compressor.input.ratio[i]     = _mm256_set1_pd(0.25); // N:1
        fx.f1_compressor.input.gain[i]      = _mm256_set1_pd(6);    // dB
    }

    // Calculate input-dependent values:
    fx.f0_gain.recalc();
    fx.f1_compressor.recalc();

    // FX parameters are all set.

#ifdef NOT_LIVE
    // Test mode:

#if 0
    const auto t0 = mm256_if_then_else(_mm256_cmp_pd(_mm256_set1_pd(-1.0), _mm256_set1_pd(0.0), _CMP_LT_OQ), _mm256_set1_pd(0.0), _mm256_set1_pd(-1.0));
    printvec_dB(t0);
    printf("\n\n");
    const auto p0 = mm256_if_then_else(_mm256_cmp_pd(_mm256_set1_pd(-1.0), _mm256_set1_pd(0.0), _CMP_LT_OQ), _mm256_set1_pd(0.0), _mm256_set1_pd(1.0));
    printvec_dB(t0);
    printf("\n\n");
    const auto t1 = mm256_if_then_else(_mm256_cmp_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(0.0), _CMP_LT_OQ), _mm256_set1_pd(0.0), _mm256_set1_pd(-1.0));
    printvec_dB(t1);
    printf("\n\n");
    const auto p1 = mm256_if_then_else(_mm256_cmp_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(0.0), _CMP_LT_OQ), _mm256_set1_pd(0.0), _mm256_set1_pd(1.0));
    printvec_dB(t1);
    printf("\n\n");
    goto done;
#endif

    vec8_i32 in, out;
    long long c = 0LL;
    for (int i = 0; i < 20; ++i)
    {
        for (int n = 0; n < 48; ++n, ++c)
        {
            double s = sin(2.0 * 3.14159265358979323846 * (double)c / drv.sampleRate);
            int si = (int)(s * INT_MAX / 2);

            in = _mm256_set1_epi32(si);

            processEffects(in, out, 0);
        }

#if 1
        printf("samp:   ");
        printvec_samp(in);
        printf("\n");

        printf("input:  ");
        for (int n = 0; n < icr; ++n)
        {
            printvec_dB(fx.fi_monitor.levels[n]);
            if (n < icr - 1) printf(" ");
        }
        printf("\n");

        printf("gain:   ");
        for (int n = 0; n < icr; ++n)
        {
            printvec_dB(fx.f0_output.levels[n]);
            if (n < icr - 1) printf(" ");
        }
        printf("\n");

        printf("comp:   ");
        for (int n = 0; n < icr; ++n)
        {
            printvec_dB(fx.fo_monitor.levels[n]);
            if (n < icr - 1) printf(" ");
        }
        printf("\n");

        printf("samp:   ");
        printvec_samp(out);
        printf("\n\n");
#endif
    }
#else
    // ASIO live engine mode:
    if (!loadAsioDriver("UA-1000"))
    {
        error = "load failed.";
        goto err;
    }

    if (ASIOInit(&drv.driver) != ASE_OK)
        goto err;

    inited = true;

    if (ASIOGetChannels(&drv.inputChannels, &drv.outputChannels) != ASE_OK)
        goto err;

    printf("in: %d, out %d\n", drv.inputChannels, drv.outputChannels);

    if (ASIOGetBufferSize(&drv.minSize, &drv.maxSize, &drv.preferredSize, &drv.granularity) != ASE_OK)
        goto err;

    printf("min buf size: %d, preferred: %d, max buf size: %d\n", drv.minSize, drv.preferredSize, drv.maxSize);

    if (ASIOGetSampleRate(&drv.sampleRate) != ASE_OK)
        goto err;

    printf("rate: %f\n\n", drv.sampleRate);

    if (ASIOOutputReady() == ASE_OK)
        drv.postOutput = true;
    else
        drv.postOutput = false;

    // fill the bufferInfos from the start without a gap
    ASIOBufferInfo *info = drv.bufferInfos;

    // prepare inputs (Though this is not necessarily required, no opened inputs will work, too
    if (drv.inputChannels > kMaxInputChannels)
        drv.inputBuffers = kMaxInputChannels;
    else
        drv.inputBuffers = drv.inputChannels;
    for (int i = 0; i < drv.inputBuffers; i++, info++)
    {
        info->isInput = ASIOTrue;
        info->channelNum = i;
        info->buffers[0] = info->buffers[1] = 0;
    }

    // prepare outputs
    if (drv.outputChannels > kMaxOutputChannels)
        drv.outputBuffers = kMaxOutputChannels;
    else
        drv.outputBuffers = drv.outputChannels;
    for (int i = 0; i < drv.outputBuffers; i++, info++)
    {
        info->isInput = ASIOFalse;
        info->channelNum = i;
        info->buffers[0] = info->buffers[1] = 0;
    }

    asioCallbacks.asioMessage = asioMessage;
    asioCallbacks.bufferSwitch = bufferSwitch;
    asioCallbacks.bufferSwitchTimeInfo = bufferSwitchTimeInfo;

    // Create the buffers:
    if (ASIOCreateBuffers(drv.bufferInfos, drv.inputBuffers + drv.outputBuffers, drv.preferredSize, &asioCallbacks) != ASE_OK)
        goto err;
    else
        buffersCreated = true;

    // now get all the buffer details, sample word length, name, word clock group and activation
    for (int i = 0; i < drv.inputBuffers + drv.outputBuffers; i++)
    {
        drv.channelInfos[i].channel = drv.bufferInfos[i].channelNum;
        drv.channelInfos[i].isInput = drv.bufferInfos[i].isInput;
        if (ASIOGetChannelInfo(&drv.channelInfos[i]) != ASE_OK)
            goto err;

        //printf("%s[%2d].type = %d\n", drv.channelInfos[i].isInput ? "in " : "out", drv.channelInfos[i].channel, drv.channelInfos[i].type);
        if (drv.channelInfos[i].type != ASIOSTInt32LSB)
        {
            error = "Application assumes sample types of ASIOSTInt32LSB!";
            goto err;
        }
    }

    // get the input and output latencies
    // Latencies often are only valid after ASIOCreateBuffers()
    // (input latency is the age of the first sample in the currently returned audio block)
    // (output latency is the time the first sample in the currently returned audio block requires to get to the output)
    if (ASIOGetLatencies(&drv.inputLatency, &drv.outputLatency) != ASE_OK)
        goto err;

    printf ("latencies: input: %d, output: %d\n", drv.inputLatency, drv.outputLatency);

    // Start the engine:
    if (ASIOStart() != ASE_OK)
        goto err;
    else
        started = true;

    printf("Engine started.\n\n");
    const int total_time = 30;
    for (int i = 0; i < total_time; ++i)
    {
        printf("Engine running %2d.   \r", total_time - i);
        Sleep(1000);
    }
#endif

    goto done;

err:
    if (error == NULL)
        error = drv.driver.errorMessage;

    if (error != NULL)
        fprintf(stderr, "%s\r\n", error);

    retval = -1;

done:
    if (started)
        ASIOStop();
    if (buffersCreated)
        ASIODisposeBuffers();
    if (inited)
        ASIOExit();
    return retval;
}
void LevelScene::update()
{
    if(m_luaEngine.shouldShutdown())
    {
        m_fader.setFade(10, 1.0, 1.0);
        setExiting(0, LvlExit::EXIT_Error);
    }

    Scene::update();

    if(!m_isPauseMenu)
        tickAnimations(uTickf);

    if(!m_isLevelContinues)
    {
        //Level exit timeout
        m_exitLevelDelay -= uTickf;

        if(m_exitLevelDelay <= 0.0)
        {
            m_doExit = true;

            if(m_fader.isNull())
            {
                if(PGE_MusPlayer::isPlaying())
                    PGE_MusPlayer::fadeOut(500);

                m_fader.setFade(10, 1.0, 0.01);
            }
        }
    }

    if(m_doExit)
    {
        if(m_exitLevelCode == LvlExit::EXIT_Closed)
        {
            m_fader.setFull();
            m_isRunning = false;
        }
        else
        {
            if(m_fader.isFull())
                m_isRunning = false;
        }
    }
    else if(m_isPauseMenu)
        processPauseMenu();
    else
    {
        //Update physics is not pause menu
        updateLua();//Process LUA code
        m_systemEvents.processEvents(uTickf);
        m_events.processTimers(uTickf);

        //update cameras
        for(PGE_LevelCamera &cam : m_cameras)
            cam.updatePre(uTickf);

        processEffects(uTickf);

        if(!m_isTimeStopped) //if activated Time stop bonus or time disabled by special event
        {
            //Make world step
            processPhysics(uTickf);
        }

        while(!m_blockTransforms.empty())
        {
            transformTask_block x = m_blockTransforms.front();
            x.block->transformTo_x(x.id);
            m_blockTransforms.pop_front();
        }

        // Send controller states to controllable objects
        m_player1Controller->sendControls();
        m_player2Controller->sendControls();

        //update players
        for(LVL_Player *plr : m_itemsPlayers)
        {
            plr->update(uTickf);

            if(PGE_Window::showDebugInfo)
            {
                m_debug_player_jumping    = plr->m_jumpPressed;
                m_debug_player_onground   = plr->onGround();
                m_debug_player_foots      = (int)plr->l_contactB.size();
            }
        }

        for(size_t i = 0; i < m_blocksInFade.size(); i++)
        {
            if(m_blocksInFade[i]->tickFader(uTickf))
            {
                m_blocksInFade.erase(m_blocksInFade.begin() + (int)i);
                i--;
            }
        }

        //Process activated NPCs
        //for(size_t i = 0; i < m_npcActive.size(); i++)
        for(auto i = m_npcActive.begin(); i != m_npcActive.end();)
        {
            LVL_Npc *n = *i;
            n->update(uTickf);
            if(n->isKilled())
            {
                i = m_npcActive.erase(i);
                continue;
            }
            else if(n->activationTimeout <= 0)
            {
                if(!n->warpSpawing)
                    n->deActivate();
                if(n->wasDeactivated)
                {
                    if(!isVizibleOnScreen(n->m_momentum) || !n->isVisible() || !n->is_activity)
                    {
                        n->wasDeactivated = false;
                        i = m_npcActive.erase(i);
                        continue;
                    }
                }
            }
            ++i;
        }

        if(!m_isTimeStopped) //if activated Time stop bonus or time disabled by special event
        {
            //Process and resolve collisions
            processAllCollisions();
        }

        /***************Collect garbage****************/
        if(!m_npcDead.empty())
            collectGarbageNPCs();

        if(!m_playersDead.empty())
            collectGarbagePlayers();

        if(!m_blocksToDelete.empty())
            collectGarbageBlocks();

        /**********************************************/

        //update cameras
        for(PGE_LevelCamera &cam : m_cameras)
        {
            cam.updatePost(uTickf);
            //! --------------DRAW HUD--------------------------------------
            // TODO: Implement separated render queue for elements of HUD and provide render functions
            // are will draw HUD elements after world has drawn.
            LuaEngine *sceneLuaEngine = getLuaEngine();
            if(sceneLuaEngine)
            {
                if(sceneLuaEngine->isValid() && !sceneLuaEngine->shouldShutdown())
                {
                    LuaEvent drawHUDEvent = BindingCore_Events_Engine::createDrawLevelHUDEvent(sceneLuaEngine,
                                            &cam,
                                            &m_playerStates[(size_t)(cam.playerID - 1)]);
                    sceneLuaEngine->dispatchEvent(drawHUDEvent);
                }
            }
            //! ------------------------------------------------------------
        }

        //Add effects into the render table
        for(Scene_Effect &item : WorkingEffects)
        {
            renderArrayAddFunction([&item](double camPosX, double camPosY)
            {
                item.render(camPosX, camPosY);
            },  item.m_zIndex);
        }

        //Clear garbage (be careful!)
        //luaEngine.runGarbageCollector();
    }

    //Process interprocessing commands cache
    process_InterprocessCommands();
    //Process Z-sort of the render functions
    renderArrayPrepare();
    //Process message boxes
    m_messages.process();
}
Esempio n. 6
0
/* Read the entire message from js, then take action.
 * Thus messages will remain in sync. */
static int readMessage(void)
{
	int l;
	char *msg;		/* error message from js */

	if (readFromJS(&head, sizeof(head)) < 0)
		return -1;	/* read failed */

	if (head.magic != EJ_MAGIC) {
/* this should never happen */
		js_kill();
		i_puts(MSG_JSEngineSync);
		markAllDead();
		return -1;
	}

	if (head.highstat >= EJ_HIGH_HEAP_FAIL) {
		js_kill();
/* perhaps a helpful message, before we close down js sessions */
		if (head.highstat == EJ_HIGH_PROC_FAIL)
			allowJS = false;
		if (head.lowstat == EJ_LOW_EXEC)
			i_puts(MSG_JSEngineExec);
		if (head.lowstat == EJ_LOW_MEMORY)
			i_puts(MSG_JavaMemError);
		if (head.lowstat == EJ_LOW_RUNTIME)
			i_puts(MSG_JSEngineRun);
		if (head.lowstat == EJ_LOW_SYNC)
			i_puts(MSG_JSEngineSync);
		markAllDead();
		return -1;
	}

	if (head.side) {
		effects = allocMem(head.side + 1);
		if (readFromJS(effects, head.side) < 0) {
			free(effects);
			effects = 0;
			return -1;
		}
		effects[head.side] = 0;
// because debugPrint always puts on a newline
		effects[head.side - 1] = 0;
		debugPrint(4, "< side effects\n%s", effects);
		processEffects();
	}

/* next grab the error message, if there is one */
	l = head.msglen;
	if (l) {
		msg = allocMem(l + 1);
		if (readFromJS(msg, l)) {
			free(msg);
			return -1;
		}
		msg[l] = 0;
		if (debugLevel >= 3) {
/* print message, this will be in English, and mostly for our debugging */
			if (jsSourceFile) {
				if (debugFile)
					fprintf(debugFile, "%s line %d: ",
						jsSourceFile, head.lineno);
				else
					printf("%s line %d: ",
					       jsSourceFile, head.lineno);
			}
			debugPrint(3, "%s", msg);
		}
		free(msg);
	}

/*  Read in the requested property, if there is one.
 * The calling function must handle the property. */
	l = head.proplength;
	proptype = head.proptype;
	if (l) {
		propval = allocMem(l + 1);
		if (readFromJS(propval, l)) {
			free(propval);
			propval = 0;
			return -1;
		}
		propval[l] = 0;
	}

/* stop at the first js error when debugging */
	if (head.msglen && debugLevel >= 5) {
		head.highstat = EJ_HIGH_CX_FAIL;
		head.lowstat = 0;
		debugPrint(5, "js abort due to error while debugging");
	}

	if (head.highstat == EJ_HIGH_CX_FAIL) {
		if (head.lowstat == EJ_LOW_VARS)
			i_puts(MSG_JSEngineVars);
		if (head.lowstat == EJ_LOW_CX)
			i_puts(MSG_JavaContextError);
		if (head.lowstat == EJ_LOW_WIN)
			i_puts(MSG_JavaWindowError);
		if (head.lowstat == EJ_LOW_DOC)
			i_puts(MSG_JavaObjError);
		if (head.lowstat == EJ_LOW_CLOSE)
			i_puts(MSG_PageDone);
		else
			i_puts(MSG_JSSessionFail);
		freeJavaContext(cw);
/* should I free and zero the property at this point? */
	}

	return 0;
}				/* readMessage */