From c3f7f72f37adad5103587069ff549798fc9d652d Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Wed, 18 Feb 2009 20:14:23 +0100 Subject: Introduced a toLower method and grouped string utils The string utility methods are now grouped together in the stringutils.h header. Also, a toLower method was added for convenience. --- src/map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 5e38aee2..b780b5cc 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -37,7 +37,7 @@ #include "resources/resourcemanager.h" #include "utils/dtor.h" -#include "utils/tostring.h" +#include "utils/stringutils.h" extern volatile int tick_time; -- cgit v1.2.3-70-g09d2 From 9e7dfd7397ed2c282015f4cc13c42598b6bb1f39 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Tue, 10 Mar 2009 05:15:20 -0600 Subject: Remove some tabs and trailing whitespace --- src/gui/chat.cpp | 16 ++++++++-------- src/gui/confirm_dialog.cpp | 4 ++-- src/gui/debugwindow.cpp | 2 +- src/gui/listbox.cpp | 2 +- src/gui/ok_dialog.cpp | 6 +++--- src/gui/setup_players.cpp | 4 ++-- src/gui/shop.h | 2 +- src/gui/widgets/dropdown.cpp | 6 +++--- src/map.cpp | 2 +- src/shopitem.h | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/map.cpp') diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 26eaf488..702327a5 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -140,12 +140,12 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord) // *implements actions in a backwards compatible way* if (own == BY_PLAYER && - tmp.text.at(0) == '*' && - tmp.text.at(tmp.text.length()-1) == '*') + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') { - tmp.text[0] = ' '; - tmp.text.erase(tmp.text.length() - 1); - own = ACT_IS; + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; } std::string lineColor = "##C"; @@ -622,9 +622,9 @@ void ChatWindow::chatSend(const std::string &nick, std::string msg) } else if (command == "me") { - std::stringstream actionStr; - actionStr << "*" << msg << "*"; - chatSend(player_node->getName(), actionStr.str()); + std::stringstream actionStr; + actionStr << "*" << msg << "*"; + chatSend(player_node->getName(), actionStr.str()); } else { diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp index fbbc6101..0d41525a 100644 --- a/src/gui/confirm_dialog.cpp +++ b/src/gui/confirm_dialog.cpp @@ -56,7 +56,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, { // fontHeight == height of each line of text (based on font heights) // 14 == row top + bottom graphic pixel heights - setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * + setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * fontHeight) + noButton->getHeight()); mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, 3 + (numRows * fontHeight))); @@ -67,7 +67,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, width = getFont()->getWidth(msg); if (width < inWidth) width = inWidth; - setContentSize(width + fontHeight, (2 * fontHeight) + + setContentSize(width + fontHeight, (2 * fontHeight) + noButton->getHeight()); mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17)); } diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 33304944..cf2f9613 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -70,7 +70,7 @@ void DebugWindow::logic() mFPSLabel->setCaption(toString(fps) + " FPS"); - mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " + + mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " + toString(mouseTileY) + ")"); Map *currentMap = engine->getCurrentMap(); diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index 2f7d2f7f..cd5aa736 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -111,7 +111,7 @@ void ListBox::keyPressed(gcn::KeyEvent& keyEvent) } else if (key.getValue() == gcn::Key::UP) { - setSelected(mSelected - 1); + setSelected(mSelected - 1); keyEvent.consume(); } else if (key.getValue() == gcn::Key::DOWN) diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp index d73c7d7c..4f4f1117 100644 --- a/src/gui/ok_dialog.cpp +++ b/src/gui/ok_dialog.cpp @@ -52,10 +52,10 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, if (numRows > 1) { // 14 == row top + bottom graphic pixel heights - setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * + setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * fontHeight) + okButton->getHeight()); - mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, - 3 + (numRows * fontHeight))); + mTextArea->setDimension(gcn::Rectangle(4, 5, + mTextBox->getMinWidth() + 5, 3 + (numRows * fontHeight))); } else { diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 96792436..84dbed55 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -329,7 +329,7 @@ void Setup_Players::apply() ~(PlayerRelation::TRADE | PlayerRelation::WHISPER); player_relations.setDefault(old_default_relations - | (mDefaultTrading->isSelected() ? + | (mDefaultTrading->isSelected() ? PlayerRelation::TRADE : 0) | (mDefaultWhisper->isSelected() ? PlayerRelation::WHISPER : 0)); @@ -341,7 +341,7 @@ void Setup_Players::cancel() void Setup_Players::action(const gcn::ActionEvent &event) { - if (event.getId() == ACTION_TABLE) + if (event.getId() == ACTION_TABLE) { // temporarily eliminate ourselves: we are fully aware of this change, // so there is no need for asynchronous updates. (In fact, thouse diff --git a/src/gui/shop.h b/src/gui/shop.h index faffe7e3..0c900d9d 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -37,7 +37,7 @@ class ShopItem; * The addItem routine can automatically check, if an item already exists and * only adds duplicates to the old item, if one is found. The original * distribution of the duplicates can be retrieved from the item. - * + * * This functionality can be enabled in the constructor. */ class ShopItems : public gcn::ListModel diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index eef9ae33..e1a24cb7 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -78,10 +78,10 @@ DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea, { for (x = 0; x < 3; x++) { - skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y], - gridx[x + 1] - + skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y], + gridx[x + 1] - gridx[x] + 1, - gridy[y + 1] - + gridy[y + 1] - gridy[y] + 1); skin.grid[a]->setAlpha(mAlpha); a++; diff --git a/src/map.cpp b/src/map.cpp index 814b4225..39e6d0a5 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -85,7 +85,7 @@ void TileAnimation::update() Image *img = mAnimation->getCurrentImage(); if (img != mLastImage) { - for (std::list >::iterator i = + for (std::list >::iterator i = mAffected.begin(); i != mAffected.end(); i++) { i->first->setTile(i->second, img); diff --git a/src/shopitem.h b/src/shopitem.h index 3b00a3c8..cbe0a06f 100644 --- a/src/shopitem.h +++ b/src/shopitem.h @@ -95,7 +95,7 @@ class ShopItem : public Item * Reduces the quantity of the topmost duplicate by the specified * amount. Also reduces the total quantity of this DuplicateItem. * Empty duplicates are automatically removed. - * + * * If the amount is bigger than the quantity of the current topmost, * only sell as much as possible. Returns the amount actually sold (do * not ignore the return value!) -- cgit v1.2.3-70-g09d2 From 2d6e867ba8306bc662b9cf42dd403f2ebcb140a6 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Tue, 10 Mar 2009 05:15:20 -0600 Subject: Remove some tabs and trailing whitespace --- src/gui/chat.cpp | 16 ++++++++-------- src/gui/confirm_dialog.cpp | 4 ++-- src/gui/debugwindow.cpp | 2 +- src/gui/listbox.cpp | 2 +- src/gui/ok_dialog.cpp | 6 +++--- src/gui/setup_players.cpp | 4 ++-- src/gui/shop.h | 2 +- src/gui/widgets/dropdown.cpp | 6 +++--- src/map.cpp | 2 +- src/shopitem.h | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/map.cpp') diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 91e410ce..47fadc8d 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -141,12 +141,12 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord) // *implements actions in a backwards compatible way* if (own == BY_PLAYER && - tmp.text.at(0) == '*' && - tmp.text.at(tmp.text.length()-1) == '*') + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') { - tmp.text[0] = ' '; - tmp.text.erase(tmp.text.length() - 1); - own = ACT_IS; + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; } std::string lineColor = "##C"; @@ -615,9 +615,9 @@ void ChatWindow::chatSend(const std::string &nick, std::string msg) } else if (command == "me") { - std::stringstream actionStr; - actionStr << "*" << msg << "*"; - chatSend(player_node->getName(), actionStr.str()); + std::stringstream actionStr; + actionStr << "*" << msg << "*"; + chatSend(player_node->getName(), actionStr.str()); } else { diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp index 2bc330c0..f4b49251 100644 --- a/src/gui/confirm_dialog.cpp +++ b/src/gui/confirm_dialog.cpp @@ -57,7 +57,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, { // fontHeight == height of each line of text (based on font heights) // 14 == row top + bottom graphic pixel heights - setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * + setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * fontHeight) + noButton->getHeight()); mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, 3 + (numRows * fontHeight))); @@ -68,7 +68,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, width = getFont()->getWidth(msg); if (width < inWidth) width = inWidth; - setContentSize(width + fontHeight, (2 * fontHeight) + + setContentSize(width + fontHeight, (2 * fontHeight) + noButton->getHeight()); mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17)); } diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 1a805dd4..dafd604a 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -71,7 +71,7 @@ void DebugWindow::logic() mFPSLabel->setCaption(toString(fps) + " FPS"); - mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " + + mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " + toString(mouseTileY) + ")"); Map *currentMap = engine->getCurrentMap(); diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index 6d5c0ca8..82011239 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -112,7 +112,7 @@ void ListBox::keyPressed(gcn::KeyEvent& keyEvent) } else if (key.getValue() == gcn::Key::UP) { - setSelected(mSelected - 1); + setSelected(mSelected - 1); keyEvent.consume(); } else if (key.getValue() == gcn::Key::DOWN) diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp index 9621b389..d3e7bec6 100644 --- a/src/gui/ok_dialog.cpp +++ b/src/gui/ok_dialog.cpp @@ -53,10 +53,10 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, if (numRows > 1) { // 14 == row top + bottom graphic pixel heights - setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * + setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) * fontHeight) + okButton->getHeight()); - mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, - 3 + (numRows * fontHeight))); + mTextArea->setDimension(gcn::Rectangle(4, 5, + mTextBox->getMinWidth() + 5, 3 + (numRows * fontHeight))); } else { diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 9105d44a..faf80640 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -330,7 +330,7 @@ void Setup_Players::apply() ~(PlayerRelation::TRADE | PlayerRelation::WHISPER); player_relations.setDefault(old_default_relations - | (mDefaultTrading->isSelected() ? + | (mDefaultTrading->isSelected() ? PlayerRelation::TRADE : 0) | (mDefaultWhisper->isSelected() ? PlayerRelation::WHISPER : 0)); @@ -342,7 +342,7 @@ void Setup_Players::cancel() void Setup_Players::action(const gcn::ActionEvent &event) { - if (event.getId() == ACTION_TABLE) + if (event.getId() == ACTION_TABLE) { // temporarily eliminate ourselves: we are fully aware of this change, // so there is no need for asynchronous updates. (In fact, thouse diff --git a/src/gui/shop.h b/src/gui/shop.h index 26a9429d..118847f9 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -38,7 +38,7 @@ class ShopItem; * The addItem routine can automatically check, if an item already exists and * only adds duplicates to the old item, if one is found. The original * distribution of the duplicates can be retrieved from the item. - * + * * This functionality can be enabled in the constructor. */ class ShopItems : public gcn::ListModel diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index 9fcf173c..035ce5d7 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -79,10 +79,10 @@ DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea, { for (x = 0; x < 3; x++) { - skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y], - gridx[x + 1] - + skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y], + gridx[x + 1] - gridx[x] + 1, - gridy[y + 1] - + gridy[y + 1] - gridy[y] + 1); skin.grid[a]->setAlpha(mAlpha); a++; diff --git a/src/map.cpp b/src/map.cpp index b780b5cc..bda618e2 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -86,7 +86,7 @@ void TileAnimation::update() Image *img = mAnimation->getCurrentImage(); if (img != mLastImage) { - for (std::list >::iterator i = + for (std::list >::iterator i = mAffected.begin(); i != mAffected.end(); i++) { i->first->setTile(i->second, img); diff --git a/src/shopitem.h b/src/shopitem.h index 18608a94..afc48bf5 100644 --- a/src/shopitem.h +++ b/src/shopitem.h @@ -96,7 +96,7 @@ class ShopItem : public Item * Reduces the quantity of the topmost duplicate by the specified * amount. Also reduces the total quantity of this DuplicateItem. * Empty duplicates are automatically removed. - * + * * If the amount is bigger than the quantity of the current topmost, * only sell as much as possible. Returns the amount actually sold (do * not ignore the return value!) -- cgit v1.2.3-70-g09d2 From 72daf0bf49c0ff994aeff357f6e52140887bce30 Mon Sep 17 00:00:00 2001 From: Ira Rice Date: Tue, 17 Mar 2009 20:18:41 -0600 Subject: Added an image merge feature loosely based on a merge function found in the open source project Wormux. To improve SDL performance, the number of layers that are pushed out to the hardware or software buffers should be reduced, which is where this function comes into play, as it combines two surfaces together so that the number of blit operations is reduced. This function is currently not used, but will be used once a good way to link each of the target systems is determined so that it only initiates when SDL is enabled, as well as making sure that each hook that uses this function is benefiting from it sufficiently. At the moment, it's suspected that the particle engine will likely be the most likely to benefit from this function, followed by tile drawing, then sprite drawing. Signed-off-by: Ira Rice --- src/map.cpp | 12 ++++---- src/openglgraphics.cpp | 1 - src/particle.cpp | 44 ++++++++++++++------------- src/resources/image.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++++++-- src/resources/image.h | 10 +++++++ 5 files changed, 117 insertions(+), 29 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index bda618e2..877a8ba9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -120,10 +120,8 @@ Image* MapLayer::getTile(int x, int y) const return mTiles[x + y * mWidth]; } -void MapLayer::draw(Graphics *graphics, - int startX, int startY, - int endX, int endY, - int scrollX, int scrollY, +void MapLayer::draw(Graphics *graphics, int startX, int startY, + int endX, int endY, int scrollX, int scrollY, const Sprites &sprites) const { startX -= mX; @@ -164,8 +162,10 @@ void MapLayer::draw(Graphics *graphics, } // Draw any remaining sprites - if (mIsFringeLayer) { - while (si != sprites.end()) { + if (mIsFringeLayer) + { + while (si != sprites.end()) + { (*si)->draw(graphics, -scrollX, -scrollY); si++; } diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index 78b502ea..df8d264f 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -233,7 +233,6 @@ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h) glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); } - void OpenGLGraphics::updateScreen() { glFlush(); diff --git a/src/particle.cpp b/src/particle.cpp index e56435ed..0e412ada 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -177,7 +177,8 @@ bool Particle::update() mVelocity *= mBounce; mVelocity.z = -mVelocity.z; } - else { + else + { mAlive = false; } } @@ -185,16 +186,12 @@ bool Particle::update() // Update child emitters if ((mLifetimePast-1)%Particle::emitterSkip == 0) { - for ( EmitterIterator e = mChildEmitters.begin(); - e != mChildEmitters.end(); - e++ - ) + for (EmitterIterator e = mChildEmitters.begin(); + e != mChildEmitters.end(); e++) { Particles newParticles = (*e)->createParticles(mLifetimePast); - for ( ParticleIterator p = newParticles.begin(); - p != newParticles.end(); - p++ - ) + for (ParticleIterator p = newParticles.begin(); + p != newParticles.end(); p++) { (*p)->moveBy(mPos); mChildParticles.push_back (*p); @@ -219,7 +216,9 @@ bool Particle::update() if ((*p)->update()) { p++; - } else { + } + else + { delete (*p); p = mChildParticles.erase(p); } @@ -237,8 +236,7 @@ void Particle::moveBy(const Vector &change) { mPos += change; for (ParticleIterator p = mChildParticles.begin(); - p != mChildParticles.end(); - p++) + p != mChildParticles.end(); p++) { if ((*p)->doesFollow()) { @@ -279,20 +277,21 @@ Particle* Particle::addEffect(const std::string &particleEffectFile, xmlNodePtr node; // Animation - if ((node = XML::findFirstChildByName( - effectChildNode, "animation"))) { + if ((node = XML::findFirstChildByName(effectChildNode, "animation"))) + { newParticle = new AnimationParticle(mMap, node); } // Image - else if ((node = XML::findFirstChildByName( - effectChildNode, "image"))) { + else if ((node = XML::findFirstChildByName(effectChildNode, "image"))) + { Image *img= resman->getImage((const char*) node->xmlChildrenNode->content); newParticle = new ImageParticle(mMap, img); } // Other - else { + else + { newParticle = new Particle(mMap); } @@ -315,7 +314,8 @@ Particle* Particle::addEffect(const std::string &particleEffectFile, continue; ParticleEmitter *newEmitter; - newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, rotation); + newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, + rotation); newParticle->addEmitter(newEmitter); } @@ -326,7 +326,8 @@ Particle* Particle::addEffect(const std::string &particleEffectFile, } Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y, - const gcn::Color *color, gcn::Font *font, bool outline) + const gcn::Color *color, + gcn::Font *font, bool outline) { Particle *newParticle = new TextParticle(mMap, text, color, font, outline); newParticle->moveTo(x, y); @@ -344,7 +345,10 @@ Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y, } Particle *Particle::addTextRiseFadeOutEffect(const std::string &text, - int x, int y, const gcn::Color *color, gcn::Font *font, bool outline){ + int x, int y, + const gcn::Color *color, + gcn::Font *font, bool outline) +{ Particle *newParticle = new TextParticle(mMap, text, color, font, outline); newParticle->moveTo(x, y); newParticle->setVelocity(0.0f, 0.0f, 0.5f); diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 7a15b762..cff40197 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -26,6 +26,7 @@ #include "image.h" #include "../log.h" +#include "../position.h" #ifdef USE_OPENGL bool Image::mUseOpenGL = false; @@ -47,8 +48,7 @@ Image::Image(SDL_Surface *image): } #ifdef USE_OPENGL -Image::Image(GLuint glimage, int width, int height, - int texWidth, int texHeight): +Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight): mGLImage(glimage), mTexWidth(texWidth), mTexHeight(texHeight), @@ -316,6 +316,81 @@ void Image::setAlpha(float a) } } +Image* Image::merge(Image* image, const Position& pos) +{ + SDL_Surface* surface = new SDL_Surface(*(image->mImage)); + + Uint32 surface_pix, cur_pix; + Uint8 r, g, b, a, p_r, p_g, p_b, p_a; + double f_a, f_ca, f_pa; + SDL_PixelFormat *current_fmt = mImage->format; + SDL_PixelFormat *surface_fmt = surface->format; + int current_offset, surface_offset; + Position offset(0, 0); + + SDL_LockSurface(surface); + SDL_LockSurface(mImage); + // for each pixel lines of a source image + for (offset.x = (pos.x > 0 ? 0 : -pos.x); offset.x < image->getWidth() && + pos.x + offset.x < getWidth(); offset.x++) + { + for (offset.y = (pos.y > 0 ? 0 : -pos.y); offset.y < image->getHeight() + && pos.y + offset.y < getHeight(); offset.y++) + { + // Computing offset on both images + current_offset = (pos.y + offset.y) * getWidth() + pos.x + offset.x; + surface_offset = offset.y * surface->w + offset.x; + + // Retrieving a pixel to merge + surface_pix = ((Uint32*) surface->pixels)[surface_offset]; + cur_pix = ((Uint32*) mImage->pixels)[current_offset]; + + // Retreiving each channel of the pixel using pixel format + r = (Uint8)(((surface_pix & surface_fmt->Rmask) >> + surface_fmt->Rshift) << surface_fmt->Rloss); + g = (Uint8)(((surface_pix & surface_fmt->Gmask) >> + surface_fmt->Gshift) << surface_fmt->Gloss); + b = (Uint8)(((surface_pix & surface_fmt->Bmask) >> + surface_fmt->Bshift) << surface_fmt->Bloss); + a = (Uint8)(((surface_pix & surface_fmt->Amask) >> + surface_fmt->Ashift) << surface_fmt->Aloss); + + // Retreiving previous alpha value + p_a = (Uint8)(((cur_pix & current_fmt->Amask) >> + current_fmt->Ashift) << current_fmt->Aloss); + + // new pixel with no alpha or nothing on previous pixel + if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0)) + ((Uint32 *)(surface->pixels))[current_offset] = + SDL_MapRGBA(current_fmt, r, g, b, a); + else if (a > 0) + { // alpha is lower => merge color with previous value + f_a = (double) a / 255.0; + f_ca = 1.0 - f_a; + f_pa = (double) p_a / 255.0; + p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >> + current_fmt->Rshift) << current_fmt->Rloss); + p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >> + current_fmt->Gshift) << current_fmt->Gloss); + p_b = (Uint8)(((cur_pix & current_fmt->Bmask) >> + current_fmt->Bshift) << current_fmt->Bloss); + r = (Uint8)((double) p_r * f_ca * f_pa + (double)r * f_a); + g = (Uint8)((double) p_g * f_ca * f_pa + (double)g * f_a); + b = (Uint8)((double) p_b * f_ca * f_pa + (double)b * f_a); + a = (a > p_a ? a : p_a); + ((Uint32 *)(surface->pixels))[current_offset] = + SDL_MapRGBA(current_fmt, r, g, b, a); + } + } + } + SDL_UnlockSurface(surface); + SDL_UnlockSurface(mImage); + + Image* newImage = new Image(surface); + + return newImage; +} + float Image::getAlpha() { return mAlpha; diff --git a/src/resources/image.h b/src/resources/image.h index 596917ce..f6b77f26 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -41,6 +41,7 @@ #include "resource.h" class Dye; +class Position; class SDL_Rect; class SDL_Surface; @@ -132,6 +133,15 @@ class Image : public Resource static void setLoadAsOpenGL(bool useOpenGL); #endif + /** + * Merges two image SDL_Surfaces together. This is for SDL use only, as + * reducing the number of surfaces that SDL has to render can cut down + * on the number of blit operations necessary, which in turn can help + * improve overall framerates. Don't use unless you are using it to + * reduce the number of overall layers that need to be drawn through SDL. + */ + Image* merge(Image* image, const Position& pos); + protected: /** * Constructor. -- cgit v1.2.3-70-g09d2