Ejemplo n.º 1
0
void GameScene::UnHit(Ref* pSender)
{
    Sprite* mole = (Sprite*)pSender;
    mole->setTag(0);
}
Ejemplo n.º 2
0
    bool Sprite::updateTransform(fzV4_T2_C4_Quad **quadp)
    {        
        FZ_ASSERT( m_mode == kFZSprite_BatchRendering, "Sprite mode is not kFZSprite_BatchRendering.");
        
        if(!m_isVisible)
            return false;
        
        
        fzV4_T2_C4_Quad *quad = *quadp;
        ++(*quadp);
        
        FZ_ASSERT( quad != NULL, "Quad cannot be NULL.");

        if( mode.B.p_currentQuad != quad) {
            mode.B.p_currentQuad = quad;
            m_dirtyFlags |= kFZDirty_transform_absolute | kFZDirty_color | kFZDirty_texcoords;
            
        }else if(m_dirtyFlags == 0)
            return false;
        
        
        // UPDATING ABSOLUTE TRANSFORM
        if( m_dirtyFlags & kFZDirty_transform_absolute )
        {
            register fzVec4 output[4];

#if FZ_SPRITE_CHILDREN || 1
            fzMath_mat4Multiply(MS::getMatrix(), getNodeToParentTransform(), m_transformMV);            
            fzMath_mat4Vec4(m_transformMV, (float*)m_vertices, (float*)output);
#else
            fzMath_mat4Vec4Affine(MS::getMatrix(), getNodeToParentTransform(), m_vertices, (float*)output);
#endif
            quad->bl.vertex = output[0];
            quad->br.vertex = output[1];
            quad->tl.vertex = output[2];
            quad->tr.vertex = output[3];
        }
        
        
        // UPDATING TEXTURE COORDS
        if( m_dirtyFlags & kFZDirty_texcoords ) {
            
            quad->bl.texCoord = m_texCoords[0];
            quad->br.texCoord = m_texCoords[1];
            quad->tl.texCoord = m_texCoords[2];
            quad->tr.texCoord = m_texCoords[3];
        }
        
        
        // UPDATING RECURSIVE OPACITY
        if(m_dirtyFlags & kFZDirty_opacity) {
            
            m_cachedOpacity = p_parent->getCachedOpacity() * m_opacity;
            m_dirtyFlags |= kFZDirty_color;
        }
        
        if(m_dirtyFlags & kFZDirty_color) {
            
            const GLubyte cachedAlpha = static_cast<GLubyte>(m_cachedOpacity * m_alpha);
            const fzColor4B color4(m_color.r, m_color.g, m_color.b, cachedAlpha);
            quad->bl.color = color4;
            quad->br.color = color4;
            quad->tl.color = color4;
            quad->tr.color = color4;            
        }
        
#if FZ_SPRITE_CHILDREN
        Sprite *child = static_cast<Sprite*>(m_children.front());
        if(child) {
            unsigned char flags = m_dirtyFlags & kFZDirty_recursive;
            
            MS::pushMatrix(m_transformMV);
            for(; child; child = static_cast<Sprite*>(child->next())) {
                child->makeDirty(flags);
                child->updateTransform(quadp);
            }
            MS::pop();
        }
#endif
        m_dirtyFlags = 0;
        
        return true;
    }
Ejemplo n.º 3
0
bool					Frame::parseXml(const rapidxml::xml_node<char> &node,
							std::string const &rootPath)
{
  //read name
  rapidxml::xml_node<char>		*nameNode = node.first_node("name");
  if (!nameNode)
    {
      std::cerr << "Error: Invalid Spriter file: Frame without name!" << std::endl;
      return false;
    }

  this->name_ = nameNode->value();

  //read and create sprites
  for (rapidxml::xml_node<char> *curNode = node.first_node("sprite");
       curNode;
       curNode = curNode->next_sibling("sprite"))
    {
      Sprite				*sprite;

      sprite = new Sprite;
      if (!sprite)
	return false;

      //get <image>
      rapidxml::xml_node<char> *node = curNode->first_node("image");
      if (!node)
	{
	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <image> node!" << std::endl;
	  return false;
	}
      if (!sprite->setBitmap(node->value(), rootPath))
	{
	  return false;
	}

      //get <color> [0x000000 ; 0xffffff]
      node = curNode->first_node("color");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <color> node!" << std::endl;
      	  return false;
      	}

      int intColor = atoi(node->value());

      //get <opacity> [0.f ; 100.f]
      node = curNode->first_node("opacity");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <opacity> node!" << std::endl;
      	  return false;
      	}
      float opacity = atof(node->value());

      int colorR = (intColor & 0xff0000) >> 16;
      int colorG = (intColor & 0x00ff00) >> 8;
      int colorB = (intColor & 0x0000ff) >> 0;
      int colorA = opacity / 100.f * 255.f;

      sprite->setColor(al_map_rgba(colorR, colorG, colorB, colorA));

      //get <angle> (in degrees, around upper left corner)
      node = curNode->first_node("angle");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <angle> node!" << std::endl;
      	  return false;
      	}

      sprite->setRotation(atof(node->value()));

      //get <width> (in pixels)
      node = curNode->first_node("width");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <width> node!" << std::endl;
      	  return false;
      	}

      sprite->setWidth(atoi(node->value()));

      //get <height> (in pixels)
      node = curNode->first_node("height");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <height> node!" << std::endl;
      	  return false;
      	}
      sprite->setHeight(atof(node->value()));

      // //get <xflip>
      // node = curNode->first_node("xflip");
      // if(!node)
      // 	{
      // 	  sf::err() << "Error: Invalid Spriter file: Frame \"" << mName << "\" lacks <xflip> node!" << std::endl;
      // 	  return false;
      // 	}
      // //            if(atoi(node->value())) width *= -1;

      // //get <yflip>
      // node = curNode->first_node("yflip");
      // if(!node)
      // 	{
      // 	  sf::err() << "Error: Invalid Spriter file: Frame \"" << mName << "\" lacks <yflip> node!" << std::endl;
      // 	  return false;
      // 	}
      // //            if(atoi(node->value())) height *= -1;

      //get <x> (in pixels)
      node = curNode->first_node("x");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <x> node!" << std::endl;
      	  return false;
      	}
      sprite->setX(atoi(node->value()));

      //get <y> (in pixels)
      node = curNode->first_node("y");
      if(!node)
      	{
      	  std::cerr << "Error: Invalid Spriter file: Frame \"" << this->name_ << "\" lacks <y> node!" << std::endl;
      	  return false;
      	}
      sprite->setY(atoi(node->value()));

      // //create Sprite
      // //width/height is negative if the axis is flipped, in that case we need to reposition the origin to upper left
      // sprite->setOrigin((width < 0 ? width : 0), (height < 0 ? height : 0));
      // sprite->setPosition(x, y);
      // sprite->setScale(width / float(tex->getSize().x), height / float(tex->getSize().y));
      // sprite->setRotation(-angle);
      // sprite->setColor(color);
      this->list_.push_back(sprite);
    }
  return true;
}
Ejemplo n.º 4
0
bool Scene::readXml(TiXmlElement* e)
{
    string objName;

    TiXmlElement* child = e->FirstChildElement();
    while(child != NULL)
    {
        if(child->ValueStr() == "pixel")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading pixel \"" << objName << "\"" << std::endl;

                Pixel* p = new Pixel(objName);
                p->loadXml(child);
                addObject(p);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load pixel without name, line "
                         << child->Row() << endl;
            }
        }

        else if(child->ValueStr() == "line")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading line \"" << objName << "\"" << std::endl;

                Line* l = new Line(objName);
                l->loadXml(child);
                addObject(l);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load line without name, line "
                         << child->Row() << endl;
            }
        }

        else if(child->ValueStr() == "rect")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading rect \"" << objName << "\"" << std::endl;

                Rect* r = new Rect(objName);
                r->loadXml(child);
                addObject(r);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load rect without name, line "
                         << child->Row() << endl;
            }
        }

        else if(child->ValueStr() == "bitmap")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading bitmap \"" << objName << "\"" << std::endl;

                Bitmap* b = new Bitmap(objName);
                b->loadXml(child);
                addObject(b);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load bitmap without name, line "
                         << child->Row() << endl;
            }
        }

        else if(child->ValueStr() == "sprite")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading sprite \"" << objName << "\"" << std::endl;

                Sprite* s = new Sprite(objName);
                s->loadXml(child);
                addObject(s);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load sprite without name, line "
                         << child->Row() << endl;
            }
        }
        
        else if(child->ValueStr() == "image")
        {
            if((objName = Xml::getAttrString(child, "name")) != "")
            {
                LOG_DEBUG << "Scene \"" << _name << "\": Loading image \"" << objName << "\"" << std::endl;

                Image* i = new Image(objName);
                i->loadXml(child);
                addObject(i);
            }
            else
            {
                LOG_WARN << "Scene \"" << _name << "\": cannot load image without name, line "
                         << child->Row() << endl;
            }
        }

		else if(child->ValueStr() != "background")
        {
            LOG_WARN << "Scene \"" << _name << "\": ignoring unknown element \""
                     << child->ValueStr() << "\"" << endl;
        }


        child = child->NextSiblingElement();
    }

    return true;
}
Ejemplo n.º 5
0
void GoToPositionBlock::executeNextStep(ExecutionThread& executionThread) const
{
    //check if block is valid for execution
    if(_xPos == NULL || _yPos == NULL)
        executionThread.endExecution(NULL);

    //get message
    ValueMessage* m = (ValueMessage*)executionThread.getMessage();
    if(m == NULL)
    {
        m = new ValueMessage();
        executionThread.setMessage(m);
    }

    //evaluate left
    if(m->getNumber() == 0)
    {
        executionThread.setNextBlock(_xPos);
        m->setNumber(1);
        return;
    }

    //evaluate right
    if(m->getNumber() == 1)
    {
        //take copy of returnValue
        m->setValue(executionThread.getReturnValue()->copy());
        //check left value
        if(m->getValue() == NULL || m->getValue()->getDataType() != Value::NUMBER)
        {
            executionThread.endExecution(NULL);
            return;
        }
        executionThread.setNextBlock(_yPos);
        m->setNumber(2);
        return;
    }

    //move sprite to position
    if(m->getNumber() == 2)
    {
        Value* v = executionThread.getReturnValue();
        //check right value
        if(v == NULL || v->getDataType() != Value::NUMBER)
        {
            executionThread.endExecution(NULL);
            return;
        }

        // move sprite
        Sprite* sprite = executionThread.getSprite();
        if(sprite != NULL) {
            int x = (int) m->getValue()->toDouble();
            int y = (int) v->toDouble();
            sprite->setPosition(QPoint(x, y));
        }
        executionThread.endExecution(NULL);
        return;
    }

    executionThread.endExecution(NULL);
}
Ejemplo n.º 6
0
void Label::alignText()
{
    if (_reusedLetter == nullptr)
    {
        return;
    }

    for (const auto& batchNode:_batchNodes)
    {
        batchNode->getTextureAtlas()->removeAllQuads();
    }
    _fontAtlas->prepareLetterDefinitions(_currentUTF16String);
    auto textures = _fontAtlas->getTextures();
    if (textures.size() > _batchNodes.size())
    {
        for (auto index = _batchNodes.size(); index < textures.size(); ++index)
        {
            auto batchNode = SpriteBatchNode::createWithTexture(textures[index]);
            batchNode->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
            batchNode->setPosition(Point::ZERO);
            Node::addChild(batchNode,0,Node::INVALID_TAG);
            _batchNodes.push_back(batchNode);
        }
    }
    LabelTextFormatter::createStringSprites(this);    
    if(_maxLineWidth > 0 && _contentSize.width > _maxLineWidth && LabelTextFormatter::multilineText(this) )      
        LabelTextFormatter::createStringSprites(this);
    
    if(_currNumLines > 1 && _alignment != TextHAlignment::LEFT)
        LabelTextFormatter::alignText(this);
  
    int strLen = cc_wcslen(_currentUTF16String);
    Rect uvRect;
    Sprite* letterSprite;
    for(const auto &child : _children) {
        int tag = child->getTag();
        if(tag >= strLen)
        {
            SpriteBatchNode::removeChild(child, true);
        }
        else if(tag >= 0)
        {
            letterSprite = dynamic_cast<Sprite*>(child);
            if (letterSprite)
            {
                uvRect.size.height = _lettersInfo[tag].def.height;
                uvRect.size.width  = _lettersInfo[tag].def.width;
                uvRect.origin.x    = _lettersInfo[tag].def.U;
                uvRect.origin.y    = _lettersInfo[tag].def.V;

                letterSprite->setTexture(textures[_lettersInfo[tag].def.textureID]);
                letterSprite->setTextureRect(uvRect);
            }          
        }
    }
    
    int index;
    for (int ctr = 0; ctr < strLen; ++ctr)
    {        
        if (_lettersInfo[ctr].def.validDefinition)
        {
            updateSpriteWithLetterDefinition(_lettersInfo[ctr].def,textures[_lettersInfo[ctr].def.textureID]);
            _reusedLetter->setPosition(_lettersInfo[ctr].position);
            index = _batchNodes[_lettersInfo[ctr].def.textureID]->getTextureAtlas()->getTotalQuads();
            _batchNodes[_lettersInfo[ctr].def.textureID]->insertQuadFromSprite(_reusedLetter,index);
        }     
    }

    updateColor();
}
Ejemplo n.º 7
0
bool WelcomeLayer::init(){
	if(!Layer::init()){
		return false;
	}
	//get the origin point of the X-Y axis, and the visiable size of the screen
	Size visiableSize = Director::getInstance()->getVisibleSize();
	Point origin = Director::getInstance()->getVisibleOrigin();

	//get the current time, the background image will selected by current time day or night: bg_day or bg_night
	time_t t = time(NULL);
	tm* lt = localtime(&t);
	int hour = lt->tm_hour;
	//create the background image according to the current time;
	Sprite *background;
	if(hour >= 6 && hour <= 17){
		 background = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("bg_day"));
	}else{
		background = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("bg_night"));
	}
	background->setAnchorPoint(Point::ZERO);
	background->setPosition(Point::ZERO);
	this->addChild(background);

	//add the word game-title to the current scene
	Sprite *title  = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("title"));
	title->setPosition(Point(origin.x + visiableSize.width/2 , (visiableSize.height * 5) / 7));
	this->addChild(title);

	//add the start-menu to the current scene
	Sprite *startButton = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("button_play"));
	Sprite *activeStartButton = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("button_play"));
	activeStartButton->setPositionY(5);
	auto menuItem  = MenuItemSprite::create(startButton,activeStartButton,NULL,CC_CALLBACK_1(WelcomeLayer::menuStartCallback, this));
	menuItem->setPosition(Point(origin.x + visiableSize.width/2 ,origin.y + visiableSize.height*2/5));

    auto menu = Menu::create(menuItem,NULL);
	menu->setPosition(Point(origin.x ,origin.y));
	this->addChild(menu,1);

	//create a bird and set the position in the center of the screen
	this->bird = BirdSprite::getInstance();
	this->bird->createBird();
	this->bird->setTag(BIRD_SPRITE_TAG);
	this->bird->setPosition(Point(origin.x + visiableSize.width / 2,origin.y + visiableSize.height*3/5 - 10));
	this->bird->idle();
	this->addChild(this->bird);

	// Add the land
	this->land1 = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("land"));
	this->land1->setAnchorPoint(Point::ZERO);
	this->land1->setPosition(Point::ZERO);
	this->addChild(this->land1);

	this->land2 = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("land"));
	this->land2->setAnchorPoint(Point::ZERO);
	this->land2->setPosition(this->land1->getContentSize().width - 2.0f, 0);
	this->addChild(this->land2);

	this->schedule(schedule_selector(WelcomeLayer::scrollLand), 0.01f);

	//add the copyright-text to the current scne
	Sprite *copyright = Sprite::createWithSpriteFrame(AtlasLoader::getInstance()->getSpriteFrameByName("brand_copyright"));
	copyright->setPosition(Point(origin.x + visiableSize.width/2, origin.y + visiableSize.height/6));
	this->addChild(copyright, 10);

	return true;
}
Ejemplo n.º 8
0
Iscript::CmdResult Image::HandleIscriptCommand(Iscript::Context *ctx, Iscript::Script *script,
                                               const Iscript::Command &cmd)
{
    using namespace Iscript::Opcode;
    switch (cmd.opcode)
    {
        case PlayFram:
            if (cmd.val + direction < grp->frame_count)
                SetFrame(cmd.val);
            else
                Warning("Iscript for image %s sets image to invalid frame %x", DebugStr().c_str(), cmd.val);
        break;
        case PlayFramTile:
            if (cmd.val + *bw::tileset < grp->frame_count)
                SetFrame(cmd.val + *bw::tileset);
        break;
        case SetHorPos:
            SetOffset(cmd.point.x, y_off);
        break;
        case SetVertPos:
            SetOffset(x_off, cmd.point.y);
        break;
        case SetPos:
            SetOffset(cmd.point.x, cmd.point.y);
        break;
        case ImgOl:
            Iscript_AddOverlay(ctx, cmd.val, x_off + cmd.point.x, y_off + cmd.point.y, true);
        break;
        case ImgUl:
            Iscript_AddOverlay(ctx, cmd.val, x_off + cmd.point.x, y_off + cmd.point.y, false);
        break;
        case ImgOlOrig:
        case SwitchUl:
        {
            Image *other = Iscript_AddOverlay(ctx, cmd.val, 0, 0, cmd.opcode == ImgOlOrig);
            if (other != nullptr && ~other->flags & ImageFlags::UseParentLo)
            {
                other->flags |= ImageFlags::UseParentLo;
                SetOffsetToParentsSpecialOverlay(other);
            }
        }
        break;
        case ImgOlUseLo:
        case ImgUlUseLo:
        {
            // Yeah, it's not actually point
            Point32 point = LoFile::GetOverlay(image_id, cmd.point.x).GetValues(this, cmd.point.y);
            Iscript_AddOverlay(ctx, cmd.val, point.x + x_off, point.y + y_off, cmd.opcode == ImgOlUseLo);
        }
        break;
        case ImgUlNextId:
            Iscript_AddOverlay(ctx, image_id + 1, cmd.point.x + x_off, cmd.point.y + y_off, false);
        break;
        case SprOl:
            // Bullet's iscript handler has an override for goliath range upgrade
            Sprite::Spawn(this, cmd.val, cmd.point, parent->elevation + 1);
        break;
        case HighSprOl:
            Sprite::Spawn(this, cmd.val, cmd.point, parent->elevation - 1);
        break;
        case LowSprUl:
            Sprite::Spawn(this, cmd.val, cmd.point, 1);
        break;
        case UflUnstable:
        {
            Warning("Flingy creation not implemented (image %s)", DebugStr().c_str());
            /*Flingy *flingy = CreateFlingy(cmd.val, parent->player, cmd.point);
            if (flingy)
            {
                flingy->GiveRandomMoveTarget(ctx->rng);
                flingy->sprite->UpdateVisibilityPoint();
            }*/
        }
        break;
        case SprUlUseLo:
        case SprUl:
        {
            int elevation = parent->elevation;
            if (cmd.opcode == SprUl)
                elevation -= 1;
            Sprite *sprite = Sprite::Spawn(this, cmd.val, cmd.point, elevation);
            if (sprite != nullptr)
            {
                if (IsFlipped())
                    sprite->SetDirection32(32 - direction);
                else
                    sprite->SetDirection32(direction);
            }
        }
        break;
        case SprOlUseLo:
        {
            // Again using the "point" for additional storage
            Point32 point = LoFile::GetOverlay(image_id, cmd.point.x).GetValues(this, 0);
            Sprite *sprite = Sprite::Spawn(this, cmd.val, point.ToPoint16(), parent->elevation + 1);
            if (sprite)
            {
                if (IsFlipped())
                    sprite->SetDirection32(32 - direction);
                else
                    sprite->SetDirection32(direction);
            }
        }
        break;
        case SetFlipState:
            SetFlipping(cmd.val);
        break;
        case PlaySnd:
        case PlaySndRand:
        case PlaySndBtwn:
        {
            int sound_id;
            if (cmd.opcode == PlaySnd)
                sound_id = cmd.val;
            else if (cmd.opcode == PlaySndRand)
                sound_id = *(uint16_t *)(cmd.data + 1 + ctx->rng->Rand(cmd.data[0]) * 2);
            else // PlaySndBtwn
                sound_id = cmd.val1() + ctx->rng->Rand(cmd.val2() - cmd.val1() + 1);
            PlaySoundAtPos(sound_id, parent->position.AsDword(), 1, 0);
        }
        break;
        case FollowMainGraphic:
            if (parent->main_image != nullptr)
            {
                Image *main_img = parent->main_image;
                if (main_img->frame != frame || main_img->IsFlipped() != IsFlipped())
                {
                    int new_frame = main_img->frameset + main_img->direction;
                    if (new_frame >= grp->frame_count)
                    {
                        Warning("Iscript for image %s requested to play frame %x with followmaingraphic",
                                DebugStr().c_str(), new_frame);
                    }
                    else
                    {
                        frameset = main_img->frameset;
                        FollowMainImage();
                    }
                }
            }
        break;
        case EngFrame:
        case EngSet:
            if (cmd.opcode == EngFrame)
                frameset = cmd.val;
            else // EndSet
                frameset = parent->main_image->frameset + parent->main_image->grp->frame_count * cmd.val;
            FollowMainImage();
        break;
        case HideCursorMarker:
            *bw::draw_cursor_marker = 0;
        break;
        case TmpRmGraphicStart:
            Hide();
        break;
        case TmpRmGraphicEnd:
            Show();
        break;
        case WarpOverlay:
            flags |= ImageFlags::Redraw;
            drawfunc_param = (void *)cmd.val;
        break;
        case GrdSprOl:
        {
            int x = parent->position.x + x_off + cmd.point.x;
            int y = parent->position.y + y_off + cmd.point.y;
            // Yes, it checks if unit id 0 can fit there
            if (DoesFitHere(Unit::Marine, x, y))
                Sprite::Spawn(this, cmd.val, cmd.point, parent->elevation + 1);
        }
        break;
        default:
            return ConstIscriptCommand(ctx, script, cmd);
        break;
    }
    return Iscript::CmdResult::Handled;
}
Ejemplo n.º 9
0
void DocumentApi::backgroundFromLayer(LayerImage* layer, int bgcolor)
{
  ASSERT(layer);
  ASSERT(layer->isImage());
  ASSERT(layer->isReadable());
  ASSERT(layer->isWritable());
  ASSERT(layer->getSprite() != NULL);
  ASSERT(layer->getSprite()->getBackgroundLayer() == NULL);

  DocumentUndo* undo = m_document->getUndo();
  Sprite* sprite = layer->getSprite();

  // create a temporary image to draw each frame of the new
  // `Background' layer
  UniquePtr<Image> bg_image_wrap(Image::create(sprite->getPixelFormat(),
                                               sprite->getWidth(),
                                               sprite->getHeight()));
  Image* bg_image = bg_image_wrap.get();

  CelIterator it = layer->getCelBegin();
  CelIterator end = layer->getCelEnd();

  for (; it != end; ++it) {
    Cel* cel = *it;
    ASSERT((cel->getImage() > 0) &&
           (cel->getImage() < sprite->getStock()->size()));

    // get the image from the sprite's stock of images
    Image* cel_image = sprite->getStock()->getImage(cel->getImage());
    ASSERT(cel_image);

    image_clear(bg_image, bgcolor);
    image_merge(bg_image, cel_image,
                cel->getX(),
                cel->getY(),
                MID(0, cel->getOpacity(), 255),
                layer->getBlendMode());

    // now we have to copy the new image (bg_image) to the cel...
    setCelPosition(sprite, cel, 0, 0);

    // same size of cel-image and bg-image
    if (bg_image->w == cel_image->w &&
        bg_image->h == cel_image->h) {
      if (undo->isEnabled())
        m_undoers->pushUndoer(new undoers::ImageArea(getObjects(),
            cel_image, 0, 0, cel_image->w, cel_image->h));

      image_copy(cel_image, bg_image, 0, 0);
    }
    else {
      replaceStockImage(sprite, cel->getImage(), Image::createCopy(bg_image));
    }
  }

  // Fill all empty cels with a flat-image filled with bgcolor
  for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) {
    Cel* cel = layer->getCel(frame);
    if (!cel) {
      Image* cel_image = Image::create(sprite->getPixelFormat(), sprite->getWidth(), sprite->getHeight());
      image_clear(cel_image, bgcolor);

      // Add the new image in the stock
      int image_index = addImageInStock(sprite, cel_image);

      // Create the new cel and add it to the new background layer
      cel = new Cel(frame, image_index);
      addCel(layer, cel);
    }
  }

  configureLayerAsBackground(layer);
}