Пример #1
0
bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
                        int16 &right, int16 &bottom) {

    if (!hasBuffer()) {
        uint16 width, height;

        _ani->getMaxSize(width, height);

        resizeBuffer(width, height);
    }

    const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
    if (_frame >= animation.frameCount)
        return false;

    const ANIFile::FrameArea &area = animation.frameAreas[_frame];

    left   = _x + area.left;
    top    = _y + area.top;
    right  = _x + area.right;
    bottom = _y + area.bottom;

    if (!saveScreen(dest, left, top, right, bottom))
        return false;

    _ani->draw(dest, _animation, _frame, _x, _y);

    return true;
}
Пример #2
0
bool ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top,
                        int16 &right, int16 &bottom) {

    if (!hasBuffer()) {
        uint16 width, height;

        _cmp->getMaxSize(width, height);

        resizeBuffer(width, height);
    }

    left   = _x;
    top    = _y;
    right  = _x + _cmp->getWidth (_animation) - 1;
    bottom = _y + _cmp->getHeight(_animation) - 1;

    if (!saveScreen(dest, left, top, right, bottom))
        return false;

    _cmp->draw(dest, _animation, _x, _y, 0);

    return true;
}
Пример #3
0
void BaseAudioEvent::mixBuffer( AudioBuffer* outputBuffer, int bufferPosition,
                                int minBufferPosition, int maxBufferPosition,
                                bool loopStarted, int loopOffset, bool useChannelRange )
{
    if ( !hasBuffer() )
        return;

    lock(); // prevents buffer mutations (from outside threads) during this read cycle

    int bufferSize = outputBuffer->bufferSize;

    // if the output channel amount differs from this events channel amount, we might
    // potentially have a bad time (e.g. engine has mono output while this event is stereo)
    // ideally events should never hold more channels than AudioEngineProps::OUTPUT_CHANNELS

    int outputChannels = std::min( _buffer->amountOfChannels, outputBuffer->amountOfChannels );
    int readPointer, i, c, ca;
    SAMPLE_TYPE* srcBuffer;
    SAMPLE_TYPE* tgtBuffer;

    // non-loopeable event whose playback is tied to the Sequencer

    if ( !_loopeable )
    {
        for ( i = 0; i < bufferSize; ++i )
        {
            readPointer = i + bufferPosition;

            // over the max position ? read from the start ( implies that sequence has started loop )
            if ( readPointer > maxBufferPosition )
            {
                if ( useChannelRange )  // TODO: channels use a min buffer position too ? (currently drummachine only)
                    readPointer -= maxBufferPosition;

                else if ( !loopStarted )
                    break;
            }

            if ( readPointer >= _sampleStart && readPointer <= _sampleEnd )
            {
                // mind the offset ! ( cached buffer starts at 0 while
                // the _sampleStart defines where the event is positioned in the sequencer )
                readPointer -= _sampleStart;

                for ( c = 0; c < outputChannels; ++c )
                {
                    srcBuffer = _buffer->getBufferForChannel( c );
                    tgtBuffer = outputBuffer->getBufferForChannel( c );

                    tgtBuffer[ i ] += ( srcBuffer[ readPointer ] * _volume );
                }
            }
            else if ( loopStarted && i >= loopOffset )
            {
                readPointer = minBufferPosition + ( i - loopOffset );

                if ( readPointer >= _sampleStart && readPointer <= _sampleEnd )
                {
                    readPointer -= _sampleStart;

                    for ( c = 0, ca = _buffer->amountOfChannels; c < ca; ++c )
                    {
                        srcBuffer = _buffer->getBufferForChannel( c );
                        tgtBuffer = outputBuffer->getBufferForChannel( c );

                        tgtBuffer[ i ] += ( srcBuffer[ readPointer ] * _volume );
                    }
                }
            }
        }
    }
    else
    {
        // loopeable events mix their buffer contents using an internal read pointer

        bool monoCopy    = _buffer->amountOfChannels < outputBuffer->amountOfChannels;
        int maxBufPos    = _buffer->bufferSize - 1;
        int writePointer = 0;
        readPointer      = _readPointer;   // use internal read pointer when reading loopeable content

        for ( i = 0; i < bufferSize; ++i, ++writePointer )
        {
            readPointer = i + bufferPosition;

            // read sample when the read pointer is within sample start and end points
            if ( readPointer >= _sampleStart && readPointer <= _sampleEnd )
            {
                // use range pointers to read within the specific sample ranges
                for ( c = 0, ca = _buffer->amountOfChannels; c < ca; ++c )
                {
                    // this sample might have less channels than the output buffer
                    if ( !monoCopy )
                        srcBuffer = _buffer->getBufferForChannel( c );
                    else
                        srcBuffer = _buffer->getBufferForChannel( 0 );

                    tgtBuffer                  = outputBuffer->getBufferForChannel( c );
                    tgtBuffer[ writePointer ] += ( srcBuffer[ _readPointer ] * _volume );
                }
                // this is a loopeable sample (thus using internal read pointer)
                // set the internal read pointer to the sample start so it keeps playing indefinitely

                if ( ++_readPointer > maxBufPos )
                    _readPointer = 0;

            }
            else if ( loopStarted && readPointer > maxBufferPosition )
            {
                // in case the Sequencers read offset exceeds the maximum and the
                // Sequencer is looping, read from start. internal _readPointer takes care of correct offset
                bufferPosition -= loopOffset;

                // decrement iterators as no write occurred in this iteration
                --i;
                --writePointer;
            }
        }
    }
    unlock();   // release lock
}