diff options
author | Philipp Sehmisch <crush@themanaworld.org> | 2009-03-18 18:37:19 +0100 |
---|---|---|
committer | Philipp Sehmisch <crush@themanaworld.org> | 2009-03-18 18:37:19 +0100 |
commit | 1231406e5c9ac43d60c6ffb0ae664970b0e4eee0 (patch) | |
tree | 45af35e9a6ee56b71f06d76efa7706bf16eaec9a | |
parent | 04c189cf7e3e8a393c81bfb3e11058ceace8802a (diff) | |
parent | 4bd8d3fd96fab681ee4520b6a6f2a6ee73f6eb97 (diff) | |
download | mana-1231406e5c9ac43d60c6ffb0ae664970b0e4eee0.tar.gz mana-1231406e5c9ac43d60c6ffb0ae664970b0e4eee0.tar.bz2 mana-1231406e5c9ac43d60c6ffb0ae664970b0e4eee0.tar.xz mana-1231406e5c9ac43d60c6ffb0ae664970b0e4eee0.zip |
Merge branch 'master' of git@gitorious.org:tmw/eathena
47 files changed, 1284 insertions, 610 deletions
@@ -1,2 +1,3 @@ Bjørn Lindeijer <bjorn@lindeijer.nl> +Majin Sniper <sniper@livecd.janhome.net> Victor Fury <frictor@unknown> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fc6d1f35..382e281c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,6 +61,8 @@ SET(SRCS gui/widgets/tab.h gui/widgets/tabbedarea.cpp gui/widgets/tabbedarea.h + gui/widgets/textpreview.cpp + gui/widgets/textpreview.h gui/browserbox.cpp gui/browserbox.h gui/buddywindow.cpp @@ -81,8 +83,6 @@ SET(SRCS gui/chatinput.h gui/checkbox.cpp gui/checkbox.h - gui/color.cpp - gui/color.h gui/confirm_dialog.cpp gui/confirm_dialog.h gui/connection.cpp @@ -140,6 +140,8 @@ SET(SRCS gui/npc_text.h gui/ok_dialog.cpp gui/ok_dialog.h + gui/palette.cpp + gui/palette.h gui/passwordfield.cpp gui/passwordfield.h gui/playerbox.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 4982c215..39fbc856 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/widgets/tab.h \ gui/widgets/tabbedarea.cpp \ gui/widgets/tabbedarea.h \ + gui/widgets/textpreview.cpp \ + gui/widgets/textpreview.h \ gui/browserbox.cpp \ gui/browserbox.h \ gui/button.cpp \ @@ -31,8 +33,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/chatinput.h \ gui/checkbox.cpp \ gui/checkbox.h \ - gui/color.cpp \ - gui/color.h \ + gui/palette.cpp \ + gui/palette.h \ gui/confirm_dialog.cpp \ gui/confirm_dialog.h \ gui/connection.cpp \ @@ -151,6 +153,7 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/textbox.h \ gui/textfield.cpp \ gui/textfield.h \ + gui/textrenderer.h \ gui/trade.cpp \ gui/trade.h \ gui/truetypefont.cpp \ diff --git a/src/being.cpp b/src/being.cpp index bf49e852..66273710 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -45,6 +45,7 @@ #include "resources/resourcemanager.h" #include "gui/gui.h" +#include "gui/palette.h" #include "gui/speechbubble.h" #include "utils/dtor.h" @@ -61,7 +62,6 @@ int Being::mNumberOfHairColors = 1; int Being::mNumberOfHairstyles = 1; std::vector<std::string> Being::hairColors; -std::vector<AnimatedSprite*> Being::emotionSet; static const int X_SPEECH_OFFSET = 18; static const int Y_SPEECH_OFFSET = 60; @@ -102,7 +102,7 @@ Being::Being(int id, int job, Map *map): mSpeechBubble = new SpeechBubble; mSpeech = ""; - mNameColor = 0x202020; + mNameColor = &guiPalette->getColor(Palette::CHAT); mText = 0; } @@ -203,17 +203,14 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type) gcn::Font *font; std::string damage = amount ? toString(amount) : type == FLEE ? "dodge" : "miss"; - - int red, green, blue; + const gcn::Color* color; font = gui->getInfoParticleFont(); // Selecting the right color if (type == CRITICAL || type == FLEE) { - red = 255; - green = 128; - blue = 0; + color = &guiPalette->getColor(Palette::HIT_CRITICAL); } else if (!amount) { @@ -221,33 +218,25 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type) { // This is intended to be the wrong direction to visually // differentiate between hits and misses - red = 0; - green = 100; - blue = 255; + color = &guiPalette->getColor(Palette::HIT_MONSTER_PLAYER); } else { - red = 255; - green = 255; - blue = 0; - } - } + color = &guiPalette->getColor(Palette::MISS); + } + } else if (getType() == MONSTER) { - red = 0; - green = 100; - blue = 255; + color = &guiPalette->getColor(Palette::HIT_PLAYER_MONSTER); } else { - red = 255; - green = 50; - blue = 50; + color = &guiPalette->getColor(Palette::HIT_MONSTER_PLAYER); } // Show damage number - particleEngine->addTextSplashEffect(damage, red, green, blue, font, - mPx + 16, mPy + 16, true); + particleEngine->addTextSplashEffect(damage, mPx + 16, mPy + 16, + color, font, true); if (amount > 0) { @@ -487,7 +476,7 @@ void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY) const int emotionIndex = mEmotion - 1; if (emotionIndex >= 0 && emotionIndex <= EmoteDB::getLast()) - emotionSet[emotionIndex]->draw(graphics, px, py); + EmoteDB::getAnimation(emotionIndex)->draw(graphics, px, py); } void Being::drawSpeech(int offsetX, int offsetY) @@ -532,7 +521,8 @@ void Being::drawSpeech(int offsetX, int offsetY) delete mText; mText = new Text(mSpeech, mPx + X_SPEECH_OFFSET, mPy - Y_SPEECH_OFFSET, - gcn::Graphics::CENTER, gcn::Color(255, 255, 255)); + gcn::Graphics::CENTER, + &guiPalette->getColor(Palette::PARTICLE)); } else if (speech == NO_SPEECH) { @@ -770,7 +760,7 @@ std::string Being::getHairColor(int index) return hairColors[index]; } -void Being::initializeHair() +void Being::load() { // Hairstyles are encoded as negative numbers. Count how far negative // we can go. @@ -809,23 +799,3 @@ void Being::initializeHair() } } } - -void Being::load() -{ - // Setup emote sprites - for (int i = 0; i <= EmoteDB::getLast(); i++) - { - EmoteInfo info = EmoteDB::get(i); - - std::string file = "graphics/sprites/" + info.sprites.front()->sprite; - int variant = info.sprites.front()->variant; - emotionSet.push_back(AnimatedSprite::load(file, variant)); - } - - initializeHair(); -} - -void Being::cleanup() -{ - delete_all(emotionSet); -}
\ No newline at end of file diff --git a/src/being.h b/src/being.h index 754c163a..ec6f1c44 100644 --- a/src/being.h +++ b/src/being.h @@ -392,8 +392,6 @@ class Being : public Sprite */ void untarget() { mUsedTargetCursor = NULL; } - AnimatedSprite* getEmote(int index) { return emotionSet[index]; } - void setEmote(Uint8 emotion, Uint8 emote_time) { mEmotion = emotion; @@ -447,8 +445,6 @@ class Being : public Sprite static void load(); - static void cleanup(); - protected: /** * Sets the new path for this being. @@ -511,10 +507,10 @@ class Being : public Sprite Uint16 mHairStyle, mHairColor; Gender mGender; int mPx, mPy; /**< Pixel coordinates */ - Uint16 mStunMode; /**< Stun mode; zero if not stunned */ + Uint16 mStunMode; /**< Stun mode; zero if not stunned */ std::set<int> mStatusEffects; /**< set of active status effects */ - gcn::Color mNameColor; + const gcn::Color* mNameColor; std::vector<AnimatedSprite*> mSprites; std::vector<int> mSpriteIDs; @@ -524,8 +520,6 @@ class Being : public Sprite ParticleList mChildParticleEffects; private: - static void initializeHair(); - /** * Calculates the offset in the given directions. * If walking in direction 'neg' the value is negated. @@ -540,8 +534,6 @@ class Being : public Sprite // Target cursor being used SimpleAnimation* mUsedTargetCursor; - - static std::vector<AnimatedSprite*> emotionSet; /**< Emoticons used by beings */ }; #endif diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp index 7bdbcbef..596174cc 100644 --- a/src/gui/browserbox.cpp +++ b/src/gui/browserbox.cpp @@ -24,8 +24,8 @@ #include <guichan/graphics.hpp> #include "browserbox.h" -#include "color.h" #include "linkhandler.h" +#include "palette.h" #include "truetypefont.h" BrowserBox::BrowserBox(unsigned int mode, bool opaque): @@ -249,16 +249,15 @@ void BrowserBox::draw(gcn::Graphics *graphics) if (mOpaque) { - graphics->setColor(gcn::Color(BGCOLOR)); + graphics->setColor(guiPalette->getColor(Palette::BACKGROUND)); graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); } if (mSelectedLink >= 0) { - bool valid; if ((mHighMode & BACKGROUND)) { - graphics->setColor(gcn::Color(textColor->getColor('H', valid))); + graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT)); graphics->fillRectangle(gcn::Rectangle( mLinks[mSelectedLink].x1, mLinks[mSelectedLink].y1, @@ -269,7 +268,7 @@ void BrowserBox::draw(gcn::Graphics *graphics) if ((mHighMode & UNDERLINE)) { - graphics->setColor(gcn::Color(textColor->getColor('<', valid))); + graphics->setColor(guiPalette->getColor(Palette::HYPERLINK)); graphics->drawLine( mLinks[mSelectedLink].x1, mLinks[mSelectedLink].y2, @@ -283,11 +282,11 @@ void BrowserBox::draw(gcn::Graphics *graphics) int link = 0; TrueTypeFont *font = static_cast<TrueTypeFont*>(getFont()); - graphics->setColor(BLACK); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++) { - int selColor = BLACK; - int prevColor = selColor; + const gcn::Color *selColor = &guiPalette->getColor(Palette::TEXT); + const gcn::Color *prevColor = selColor; std::string row = *(i); bool wrapped = false; x = 0; @@ -335,7 +334,7 @@ void BrowserBox::draw(gcn::Graphics *graphics) else { bool valid; - int rgb = textColor->getColor(c, valid); + const gcn::Color *col = &guiPalette->getColor(c, valid); if (c == '<') { const int size = mLinks[link].x2 - mLinks[link].x1; @@ -348,7 +347,7 @@ void BrowserBox::draw(gcn::Graphics *graphics) } if (valid) { - selColor = rgb; + selColor = col; } } start += 3; @@ -358,7 +357,7 @@ void BrowserBox::draw(gcn::Graphics *graphics) break; } } - graphics->setColor(gcn::Color(selColor)); + graphics->setColor(*selColor); } std::string::size_type len = diff --git a/src/gui/color.cpp b/src/gui/color.cpp deleted file mode 100644 index f9b89857..00000000 --- a/src/gui/color.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Configurable text colors - * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> - * - * This file is part of The Mana World. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "color.h" - -#include "../configuration.h" - -#include "../utils/gettext.h" -#include "../utils/stringutils.h" - -Color::Color() -{ - addColor('C', 0x000000, _("Chat")); - addColor('G', 0xff0000, _("GM")); - addColor('H', 0xebc873, _("Highlight")); - addColor('Y', 0x1fa052, _("Player")); - addColor('W', 0x0000ff, _("Whisper")); - addColor('I', 0xa08527, _("Is")); - addColor('P', 0xff00d8, _("Party")); - addColor('S', 0x8415e2, _("Server")); - addColor('L', 0x919191, _("Logger")); - addColor('<', 0xe50d0d, _("Hyperlink")); - commit(); -} - -Color::~Color() -{ - for (ColVector::iterator col = mColVector.begin(), - colEnd = mColVector.end(); - col != colEnd; - ++col) - { - config.setValue("Color" + col->text, toString(col->rgb)); - } -} - -void Color::setColor(char c, int rgb) -{ - for (ColVector::iterator col = mColVector.begin(), - colEnd = mColVector.end(); - col != colEnd; - ++col) - { - if (col->ch == c) - { - col->rgb = rgb; - return; - } - } -} - -int Color::getColor(char c, bool &valid) const -{ - for (ColVector::const_iterator col = mColVector.begin(), - colEnd = mColVector.end(); - col != colEnd; - ++col) - { - if (col->ch == c) - { - valid = true; - return col->rgb; - } - } - valid = false; - return 0x000000; -} - -std::string Color::getElementAt(int i) -{ - if (i < 0 || i >= getNumberOfElements()) - { - return ""; - } - return mColVector[i].text; -} - -char Color::getColorCharAt(int i) -{ - if (i < 0 || i >= getNumberOfElements()) - { - return 'C'; - } - return mColVector[i].ch; -} - -void Color::addColor(char c, int rgb, const std::string &text) -{ - int trueRgb = (int) config.getValue("Color" + text, rgb); - mColVector.push_back(ColorElem(c, trueRgb, text)); -} - -int Color::getColorAt(int i) -{ - if (i < 0 || i >= getNumberOfElements()) - { - return 0; - } - return mColVector[i].rgb; -} - -void Color::setColorAt(int i, int rgb) -{ - if (i >= 0 && i < getNumberOfElements()) - { - mColVector[i].rgb = rgb; - } -} - -void Color::commit() -{ - for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); - i != iEnd; - ++i) - { - i->committedRgb = i->rgb; - } -} - -void Color::rollback() -{ - for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); - i != iEnd; - ++i) - { - i->rgb = i->committedRgb; - } -} diff --git a/src/gui/color.h b/src/gui/color.h deleted file mode 100644 index 2816cedc..00000000 --- a/src/gui/color.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Configurable text colors - * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> - * - * This file is part of The Mana World. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef COLOR_H -#define COLOR_H - -#include <string> -#include <vector> - -#include <guichan/listmodel.hpp> - -class Color : public gcn::ListModel -{ - public: - /** - * Constructor - */ - Color(); - - /** - * Destructor - */ - ~Color(); - - /** - * Define the color replacement for a character - * - * @param c charater to be replaced - * @param rgb color to replace character - */ - void setColor(char c, int rgb); - - /** - * Define the color replacement for a character - * - * @param c character to be replaced - * @param r red component - * @param g green component - * @param b blue component - */ - void setColor(char c, int r, int g, int b) - { - setColor(c, (r << 16) | (g << 8) | b); - } - - /** - * Return the color associated with a character, if exists - * - * @param c character requested - * @param valid indicate whether character is known - */ - int getColor(char c, bool &valid) const; - - /** - * Return the number of colors known - */ - int getNumberOfElements() { return mColVector.size(); } - - /** - * Return the name of the ith color - * - * @param i index of color interested in - */ - std::string getElementAt(int i); - - /** - * Get the color for the element at index i in the current color - * model - */ - int getColorAt(int i); - - /** - * Get the character used by the color for the element at index i in - * the current color model - */ - char getColorCharAt(int i); - - /** - * Set the color for the element at index i - */ - void setColorAt(int i, int rgb); - - /** - * Commit the colors - */ - void commit(); - - /** - * Rollback the colors - */ - void rollback(); - - private: - struct ColorElem - { - ColorElem(char c, int rgb, const std::string &text) : - ch(c), rgb(rgb), text(text) {} - char ch; - int rgb; - int committedRgb; - std::string text; - }; - typedef std::vector<ColorElem> ColVector; - ColVector mColVector; - - /** - * Initialise color - * - * @param c character that needs initialising - * @param rgb default color if not found in config - * @param text identifier of color - */ - void addColor(char c, int rgb, const std::string &text); -}; - -extern Color *textColor; - -#endif diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp index ad3f5c83..ececd9aa 100644 --- a/src/gui/emotecontainer.cpp +++ b/src/gui/emotecontainer.cpp @@ -53,7 +53,7 @@ EmoteContainer::EmoteContainer(): // Setup emote sprites for (int i = 0; i <= EmoteDB::getLast(); i++) { - mEmoteImg.push_back(player_node->getEmote(i)); + mEmoteImg.push_back(EmoteDB::getAnimation(i)); } mSelImg = resman->getImage("graphics/gui/selection.png"); diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h index fefce793..88df29fc 100644 --- a/src/gui/emotecontainer.h +++ b/src/gui/emotecontainer.h @@ -121,7 +121,7 @@ class EmoteContainer : public gcn::Widget, */ void distributeValueChangedEvent(void); - std::vector<AnimatedSprite*> mEmoteImg; + std::vector<const AnimatedSprite*> mEmoteImg; Image *mSelImg; int mSelectedEmoteIndex; diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp index df1bf74c..c96ea855 100644 --- a/src/gui/emoteshortcutcontainer.cpp +++ b/src/gui/emoteshortcutcontainer.cpp @@ -59,7 +59,7 @@ EmoteShortcutContainer::EmoteShortcutContainer(): // Setup emote sprites for (int i = 0; i <= EmoteDB::getLast(); i++) { - mEmoteImg.push_back(player_node->getEmote(i)); + mEmoteImg.push_back(EmoteDB::getAnimation(i)); } mMaxItems = EmoteDB::getLast() < MAX_ITEMS ? EmoteDB::getLast() : MAX_ITEMS; @@ -112,7 +112,7 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics) if (mEmoteMoved) { // Draw the emote image being dragged by the cursor. - AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1]; + const AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1]; if (sprite) { const int tPosX = mCursorPosX - (sprite->getWidth() / 2); diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h index d32a9f79..2997cb09 100644 --- a/src/gui/emoteshortcutcontainer.h +++ b/src/gui/emoteshortcutcontainer.h @@ -68,7 +68,7 @@ class EmoteShortcutContainer : public ShortcutContainer void mouseReleased(gcn::MouseEvent &event); private: - std::vector<AnimatedSprite*> mEmoteImg; + std::vector<const AnimatedSprite*> mEmoteImg; bool mEmoteClicked; int mEmoteMoved; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 6d6ccbdf..4081eeac 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -25,6 +25,7 @@ #include "focushandler.h" #include "gui.h" +#include "palette.h" #include "sdlinput.h" #include "truetypefont.h" #include "viewport.h" @@ -46,11 +47,6 @@ Gui *gui = 0; Viewport *viewport = 0; /**< Viewport on the map. */ SDLInput *guiInput = 0; -// Fonts used in showing hits -gcn::Font *hitRedFont = 0; -gcn::Font *hitBlueFont = 0; -gcn::Font *hitYellowFont = 0; - // Bolded font gcn::Font *boldFont = 0; @@ -175,6 +171,8 @@ void Gui::logic() else mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f); + guiPalette->advanceGradient(); + gcn::Gui::logic(); } diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index cd5aa736..7ba84ee7 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -24,8 +24,8 @@ #include <guichan/key.hpp> #include <guichan/listmodel.hpp> -#include "color.h" #include "listbox.h" +#include "palette.h" #include "../configuration.h" @@ -44,13 +44,8 @@ void ListBox::draw(gcn::Graphics *graphics) if (config.getValue("guialpha", 0.8) != mAlpha) mAlpha = config.getValue("guialpha", 0.8); - bool valid; - const int red = (textColor->getColor('H', valid) >> 16) & 0xFF; - const int green = (textColor->getColor('H', valid) >> 8) & 0xFF; - const int blue = textColor->getColor('H', valid) & 0xFF; - const int alpha = (int)(mAlpha * 255.0f); - - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, + (int)(mAlpha * 255.0f))); graphics->setFont(getFont()); const int fontHeight = getFont()->getHeight(); @@ -61,7 +56,7 @@ void ListBox::draw(gcn::Graphics *graphics) getWidth(), fontHeight)); // Draw the list elements - graphics->setColor(gcn::Color(0, 0, 0, 255)); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); for (int i = 0, y = 0; i < mListModel->getNumberOfElements(); ++i, y += fontHeight) { diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp new file mode 100644 index 00000000..bb2245ce --- /dev/null +++ b/src/gui/palette.cpp @@ -0,0 +1,314 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <math.h> + +#include "palette.h" +#include "gui.h" + +#include "../configuration.h" +#include "../game.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +const gcn::Color Palette::BLACK = gcn::Color(0, 0, 0); + +const gcn::Color Palette::RAINBOW_COLORS[8] = { + gcn::Color(255, 0, 0), + gcn::Color(255, 153, 0), + gcn::Color(255, 255, 0), + gcn::Color(0, 153, 0), + gcn::Color(0, 204, 204), + gcn::Color(51, 0, 153), + gcn::Color(153, 0, 153) +}; +/** Number of Elemets of RAINBOW_COLORS */ +const int Palette::RAINBOW_COLOR_COUNT = 7; + +std::string Palette::getConfigName(const std::string& typeName) +{ + std::string res = "Color" + typeName; + + int pos = 5; + for (int i = 0; i < typeName.length(); i++) + { + if (i==0 || typeName[i] == '_') + { + if (i > 0) + { + i++; + } + res[pos] = typeName[i]; + } + else + { + res[pos] = tolower(typeName[i]); + } + pos++; + } + res.erase(pos, res.length() - pos); + + return res; +} + +DEFENUMNAMES(ColorType, COLOR_TYPE); + +const int Palette::GRADIENT_DELAY = 20; + +Palette::Palette() : mColVector(ColVector(TYPE_COUNT)), mGradVector(), + mRainbowTime(tick_time) +{ + std::string indent = " "; + addColor(TEXT, 0x000000, STATIC, _("Text")); + addColor(SHADOW, 0x000000, STATIC, indent + _("Text Shadow")); + addColor(OUTLINE, 0x000000, STATIC, indent + _("Text Outline")); + + addColor(BACKGROUND, 0xffffff, STATIC, _("Background")); + + addColor(HIGHLIGHT, 0xebc873, STATIC, _("Highlight"), 'H'); + addColor(SHOP_WARNING, 0x910000, STATIC, indent + + _("Item too expensive")); + + addColor(CHAT, 0x000000, STATIC, _("Chat"), 'C'); + addColor(GM, 0xff0000, STATIC, indent + _("GM"), 'G'); + addColor(PLAYER, 0x1fa052, STATIC, indent + _("Player"), 'Y'); + addColor(WHISPER, 0x0000ff, STATIC, indent + _("Whisper"), 'W'); + addColor(IS, 0xa08527, STATIC, indent + _("Is"), 'I'); + addColor(PARTY, 0xff00d8, STATIC, indent + _("Party"), 'P'); + addColor(SERVER, 0x8415e2, STATIC, indent + _("Server"), 'S'); + addColor(LOGGER, 0x919191, STATIC, indent + _("Logger"), 'L'); + addColor(HYPERLINK, 0xe50d0d, STATIC, indent + _("Hyperlink"), '<'); + + addColor(BEING, 0xffffff, STATIC, _("Being")); + addColor(PC, 0xffffff, STATIC, indent + _("Other Player's Names")); + addColor(SELF, 0xff8040, STATIC, indent + _("Own Name")); + addColor(GM_NAME, 0x00ff00, STATIC, indent + _("GM Names")); + addColor(NPC, 0xc8c8ff, STATIC, indent + _("NPCs")); + addColor(MONSTER, 0xff4040, STATIC, indent + _("Monsters")); + + addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects")); + addColor(PICKUP_INFO, 0x28dc28, STATIC, indent + _("Pickup Notification")); + addColor(EXP_INFO, 0xffff00, STATIC, indent + _("Exp Notification")); + addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC, + indent + _("Player hits Monster")); + addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC, + indent + _("Monster hits Player")); + addColor(HIT_CRITICAL, 0xff0000, RAINBOW, indent + _("Critical Hit")); + addColor(MISS, 0xffff00, STATIC, indent + _("Misses")); + commit(true); +} + +Palette::~Palette() +{ + const std::string *configName; + for (ColVector::iterator col = mColVector.begin(), + colEnd = mColVector.end(); + col != colEnd; ++col) + { + configName = &ColorTypeNames[col->type]; + config.setValue(*configName + "Gradient", col->committedGrad); + if (col->grad == STATIC) + { + config.setValue(*configName, toString(col->getRGB())); + } + } +} + +const gcn::Color& Palette::getColor(char c, bool &valid) + { + for (ColVector::const_iterator col = mColVector.begin(), + colEnd = mColVector.end(); col != colEnd; ++col) + { + if (col->ch == c) + { + valid = true; + return col->color; + } + } + valid = false; + return BLACK; +} + +void Palette::setColor(ColorType type, int r, int g, int b) +{ + mColVector[type].color.r = r; + mColVector[type].color.g = g; + mColVector[type].color.b = b; +} + +void Palette::setGradient(ColorType type, GradientType grad) +{ + ColorElem *elem = &mColVector[type]; + if (elem->grad != STATIC && grad == STATIC) + { + for (int i = 0; i < mGradVector.size(); i++) + { + if (mGradVector[i] == elem) + { + mGradVector.erase(mGradVector.begin() + i); + break; + } + } + } + else if (elem->grad == STATIC && grad != STATIC) + { + mGradVector.push_back(elem); + } + + if (elem->grad != grad) + { + elem->grad = grad; + } +} + +std::string Palette::getElementAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return mColVector[i].text; +} + +Palette::ColorType Palette::getColorTypeAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return CHAT; + } + return mColVector[i].type; +} + +void Palette::commit(bool commitNonStatic) +{ + for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); + i != iEnd; ++i) + { + i->committedGrad = i->grad; + if (commitNonStatic || i->grad == STATIC) + { + i->committedColor = i->color; + } + } +} + +void Palette::rollback() +{ + for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); + i != iEnd; + ++i) + { + if (i->grad != i->committedGrad) + { + setGradient(i->type, i->committedGrad); + } + setColor(i->type, i->committedColor.r, i->committedColor.g, + i->committedColor.b); + } +} + +void Palette::addColor(Palette::ColorType type, int rgb, + Palette::GradientType grad, + const std::string &text, char c) +{ + const std::string *configName = &ColorTypeNames[type]; + gcn::Color trueCol = (int)config.getValue(*configName, rgb); + grad = (GradientType)config.getValue(*configName + "Gradient", grad); + mColVector[type].set(type, trueCol, grad, text, c); + if (grad != STATIC) + { + mGradVector.push_back(&mColVector[type]); + } +} + +void Palette::advanceGradient () +{ + if (get_elapsed_time(mRainbowTime) > 5) + { + int pos, colIndex, colVal; + // For slower systems, advance can be greater than one (adcanve > 1 + // skips advance-1 steps). Should make gradient look the same + // independent of the framerate. + int advance = get_elapsed_time(mRainbowTime) / 5; + double startColVal, destColVal; + + for (int i = 0; i < mGradVector.size(); i++) + { + mGradVector[i]->gradientIndex = + (mGradVector[i]->gradientIndex + advance) % + (GRADIENT_DELAY * + ((mGradVector[i]->grad == SPECTRUM) ? 6 : + RAINBOW_COLOR_COUNT)); + + pos = mGradVector[i]->gradientIndex % GRADIENT_DELAY; + colIndex = mGradVector[i]->gradientIndex / GRADIENT_DELAY; + + if (mGradVector[i]->grad == SPECTRUM) + { + if (colIndex % 2) + { // falling curve + colVal = (int)(255.0 * + (cos(M_PI * pos / GRADIENT_DELAY) + 1) / 2); + } + else + { // ascending curve + colVal = (int)(255.0 * + (cos(M_PI * (GRADIENT_DELAY-pos) / GRADIENT_DELAY) + + 1) / 2); + } + + mGradVector[i]->color.r = + (colIndex == 0 || colIndex == 5) ? 255 : + (colIndex == 1 || colIndex == 4) ? colVal : 0; + mGradVector[i]->color.g = + (colIndex == 1 || colIndex == 2) ? 255 : + (colIndex == 0 || colIndex == 3) ? colVal : 0; + mGradVector[i]->color.b = + (colIndex == 3 || colIndex == 4) ? 255 : + (colIndex == 2 || colIndex == 5) ? colVal : 0; + } + else + { + const gcn::Color* startCol = &RAINBOW_COLORS[colIndex]; + const gcn::Color* destCol = + &RAINBOW_COLORS[(colIndex + 1) % RAINBOW_COLOR_COUNT]; + + startColVal = (cos(M_PI * pos / GRADIENT_DELAY) + 1) / 2; + destColVal = 1 - startColVal; + + mGradVector[i]->color.r =(int)( + startColVal * startCol->r + + destColVal * destCol->r); + + mGradVector[i]->color.g =(int)( + startColVal * startCol->g + + destColVal * destCol->g); + + mGradVector[i]->color.b =(int)( + startColVal * startCol->b + + destColVal * destCol->b); + } + } + + mRainbowTime = tick_time; + } +} diff --git a/src/gui/palette.h b/src/gui/palette.h new file mode 100644 index 00000000..77ead4f6 --- /dev/null +++ b/src/gui/palette.h @@ -0,0 +1,308 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALETTE_H +#define PALETTE_H + +#include <cstdlib> +#include <string> +#include <vector> + +#include <guichan/listmodel.hpp> +#include <guichan/color.hpp> + +// Generate strings from an enum ... some preprocessor fun. +#define EDEF(a) a, +#define ECONFIGSTR(a) Palette::getConfigName(#a), + +#define TEXTENUM(name,def)\ + enum name { def(EDEF) };\ + static const std::string name ## Names[]; +#define DEFENUMNAMES(name,def)\ + const std::string Palette::name ## Names[] = { def(ECONFIGSTR) "" }; + +/** + * Class controlling the game's color palette. + */ +class Palette : public gcn::ListModel +{ + public: + /** List of all colors that are configurable. */ + #define COLOR_TYPE(ENTRY)\ + ENTRY(TEXT)\ + ENTRY(SHADOW)\ + ENTRY(OUTLINE)\ + ENTRY(BACKGROUND)\ + ENTRY(HIGHLIGHT)\ + ENTRY(SHOP_WARNING)\ + ENTRY(CHAT)\ + ENTRY(GM)\ + ENTRY(PLAYER)\ + ENTRY(WHISPER)\ + ENTRY(IS)\ + ENTRY(PARTY)\ + ENTRY(SERVER)\ + ENTRY(LOGGER)\ + ENTRY(HYPERLINK)\ + ENTRY(BEING)\ + ENTRY(PC)\ + ENTRY(SELF)\ + ENTRY(GM_NAME)\ + ENTRY(NPC)\ + ENTRY(MONSTER)\ + ENTRY(PARTICLE)\ + ENTRY(EXP_INFO)\ + ENTRY(PICKUP_INFO)\ + ENTRY(HIT_PLAYER_MONSTER)\ + ENTRY(HIT_MONSTER_PLAYER)\ + ENTRY(HIT_CRITICAL)\ + ENTRY(MISS)\ + ENTRY(TYPE_COUNT)\ + + TEXTENUM(ColorType, COLOR_TYPE); + + /** Colors can be static or can alter over time. */ + enum GradientType { + STATIC, + SPECTRUM, + RAINBOW + }; + + /** + * Constructor + */ + Palette(); + + /** + * Destructor + */ + ~Palette(); + + /** + * Returns the color associated with a character, if it exists. Returns + * Palette::BLACK if the character is not found. + * + * @param c character requested + * @param valid indicate whether character is known + * + * @return the requested color or Palette::BLACK + */ + const gcn::Color& getColor(char c, bool &valid); + + /** + * Gets the color associated with the type. Sets the alpha channel + * before returning. + * + * @param type the color type requested + * @param alpha alpha channel to use + * + * @return the requested color + */ + inline const gcn::Color& getColor(ColorType type, int alpha = 255) + { + gcn::Color* col = &mColVector[type].color; + col->a = alpha; + return *col; + } + + /** + * Gets the committed color associated with the specified type. + * + * @param type the color type requested + * + * @return the requested committed color + */ + inline const gcn::Color& getCommittedColor(ColorType type) + { + return mColVector[type].committedColor; + } + + /** + * Gets the GradientType associated with the specified type. + * + * @param type the color type of the color + * + * @return the gradient type of the color with the given index + */ + inline GradientType getGradientType(ColorType type) + { + return mColVector[type].grad; + } + + /** + * Get the character used by the specified color. + * + * @param type the color type of the color + * + * @return the color char of the color with the given index + */ + inline char getColorChar(ColorType type) + { + return mColVector[type].ch; + } + + /** + * Sets the color for the specified type. + * + * @param type color to be set + * @param r red component + * @param g green component + * @param b blue component + */ + void setColor(ColorType type, int r, int g, int b); + + /** + * Sets the gradient type for the specified color. + * + * @param grad gradient type to set + */ + void setGradient(ColorType type, GradientType grad); + + /** + * Returns the number of colors known. + * + * @return the number of colors known + */ + inline int getNumberOfElements() { return mColVector.size(); } + + /** + * Returns the name of the ith color. + * + * @param i index of color interested in + * + * @return the name of the color + */ + std::string getElementAt(int i); + + /** + * Gets the ColorType used by the color for the element at index i in + * the current color model. + * + * @param i the index of the color + * + * @return the color type of the color with the given index + */ + ColorType getColorTypeAt(int i); + + /** + * Commit the colors + */ + inline void commit() + { + commit(false); + } + + /** + * Rollback the colors + */ + void rollback(); + + /** + * Updates all colors, that are non-static. + */ + void advanceGradient(); + + private: + /** Black Color Constant */ + static const gcn::Color BLACK; + + /** Colors used for the rainbow gradient */ + static const gcn::Color RAINBOW_COLORS[]; + static const int RAINBOW_COLOR_COUNT; + /** Parameter to control the speed of the gradient */ + static const int GRADIENT_DELAY; + /** Time tick, that gradient-type colors were updated the last time. */ + int mRainbowTime; + + /** + * Define a color replacement. + * + * @param i the index of the color to replace + * @param r red component + * @param g green component + * @param b blue component + */ + void setColorAt(int i, int r, int g, int b); + + /** + * Commit the colors. Commit the non-static color values, if + * commitNonStatic is true. Only needed in the constructor. + */ + void commit(bool commitNonStatic); + + struct ColorElem + { + ColorType type; + gcn::Color color; + gcn::Color committedColor; + std::string text; + char ch; + GradientType grad; + GradientType committedGrad; + int gradientIndex; + + void set(ColorType type, gcn::Color& color, GradientType grad, + const std::string &text, char c) + { + ColorElem::type = type; + ColorElem::color = color; + ColorElem::text = text; + ColorElem::ch = c; + ColorElem::grad = grad; + ColorElem::gradientIndex = rand(); + } + + inline int getRGB() { + return (committedColor.r << 16) | (committedColor.g << 8) | + committedColor.b; + } + }; + typedef std::vector<ColorElem> ColVector; + /** Vector containing the colors. */ + ColVector mColVector; + std::vector<ColorElem*> mGradVector; + + /** + * Initialise color + * + * @param c character that needs initialising + * @param rgb default color if not found in config + * @param text identifier of color + */ + void addColor(ColorType type, int rgb, GradientType grad, + const std::string &text, char c = 0); + + /** + * Prefixes the given string with "Color", lowercases all letters but + * the first and all following a '_'. All '_'s will be removed. + * + * E.g.: HIT_PLAYER_MONSTER -> HitPlayerMonster + * + * @param typeName string to transform + * + * @return the transformed string + */ + static std::string getConfigName(const std::string& typeName); +}; + +extern Palette *guiPalette; + +#endif diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp index 2610be03..b786a7fa 100644 --- a/src/gui/setup_colors.cpp +++ b/src/gui/setup_colors.cpp @@ -27,9 +27,10 @@ #include <guichan/widgets/slider.hpp> #include "browserbox.h" -#include "color.h" +#include "gui.h" #include "itemlinkhandler.h" #include "listbox.h" +#include "palette.h" #include "scrollarea.h" #include "setup_colors.h" #include "slider.h" @@ -42,20 +43,24 @@ #include "../utils/gettext.h" #include "../utils/stringutils.h" +const std::string Setup_Colors::rawmsg = _("This is what the color looks like"); + Setup_Colors::Setup_Colors() : mSelected(-1) { setOpaque(false); - mColorBox = new ListBox(textColor); + mColorBox = new ListBox(guiPalette); mColorBox->setActionEventId("color_box"); mColorBox->addActionListener(this); mScroll = new ScrollArea(mColorBox); mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mTextPreview = new TextPreview(&rawmsg); + mPreview = new BrowserBox(BrowserBox::AUTO_WRAP); - mPreview->setOpaque(false); + mPreview->setOpaque(true); // don't do anything with links mPreview->setLinkHandler(NULL); @@ -65,6 +70,17 @@ Setup_Colors::Setup_Colors() : mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_NEVER); + mGradTypeLabel = new gcn::Label(_("Type: ")); + + mGradTypeSlider = new Slider(0, 2); + mGradTypeSlider->setWidth(160); + mGradTypeSlider->setActionEventId("slider_grad"); + mGradTypeSlider->setValue(0); + mGradTypeSlider->addActionListener(this); + mGradTypeSlider->setEnabled(false); + + mGradTypeText = new gcn::Label(); + mRedLabel = new gcn::Label(_("Red: ")); mRedText = new TextField; @@ -72,12 +88,14 @@ Setup_Colors::Setup_Colors() : mRedText->setRange(0, 255); mRedText->setNumeric(true); mRedText->addListener(this); + mRedText->setEnabled(false); mRedSlider = new Slider(0, 255); mRedSlider->setWidth(160); mRedSlider->setValue(mRedText->getValue()); mRedSlider->setActionEventId("slider_red"); mRedSlider->addActionListener(this); + mRedSlider->setEnabled(false); mGreenLabel = new gcn::Label(_("Green: ")); @@ -86,12 +104,14 @@ Setup_Colors::Setup_Colors() : mGreenText->setRange(0, 255); mGreenText->setNumeric(true); mGreenText->addListener(this); + mGreenText->setEnabled(false); mGreenSlider = new Slider(0, 255); mGreenSlider->setWidth(160); mGreenSlider->setValue(mGreenText->getValue()); mGreenSlider->setActionEventId("slider_green"); mGreenSlider->addActionListener(this); + mGreenSlider->setEnabled(false); mBlueLabel = new gcn::Label(_("Blue: ")); @@ -100,12 +120,14 @@ Setup_Colors::Setup_Colors() : mBlueText->setRange(0, 255); mBlueText->setNumeric(true); mBlueText->addListener(this); + mBlueText->setEnabled(false); mBlueSlider = new Slider(0, 255); mBlueSlider->setWidth(160); mBlueSlider->setValue(mBlueText->getValue()); mBlueSlider->setActionEventId("slider_blue"); mBlueSlider->addActionListener(this); + mBlueSlider->setEnabled(false); setOpaque(false); @@ -113,8 +135,11 @@ Setup_Colors::Setup_Colors() : LayoutHelper h(this); ContainerPlacer place = h.getPlacer(0, 0); - place(0, 0, mScroll, 4, 7).setPadding(2); - place(0, 7, mPreviewBox, 4).setPadding(2); + place(0, 0, mScroll, 4, 6).setPadding(2); + place(0, 6, mPreviewBox, 4).setPadding(2); + place(0, 7, mGradTypeLabel, 2); + place(2, 7, mGradTypeSlider); + place(3, 7, mGradTypeText); place(0, 8, mRedLabel, 2); place(2, 8, mRedSlider); place(3, 8, mRedText).setPadding(1); @@ -130,19 +155,14 @@ Setup_Colors::Setup_Colors() : Setup_Colors::~Setup_Colors() { - delete mRedLabel; - delete mRedSlider; - delete mRedText; - - delete mGreenLabel; - delete mGreenSlider; - delete mGreenText; - - delete mBlueLabel; - delete mBlueSlider; - delete mBlueText; - - delete mScroll; + if (mPreviewBox->getContent() == mPreview) + { + delete mTextPreview; + } + else + { + delete mPreview; + } } void Setup_Colors::action(const gcn::ActionEvent &event) @@ -150,22 +170,102 @@ void Setup_Colors::action(const gcn::ActionEvent &event) if (event.getId() == "color_box") { mSelected = mColorBox->getSelected(); - int col = textColor->getColorAt(mSelected); - char ch = textColor->getColorCharAt(mSelected); - std::string msg; + Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); + const gcn::Color *col = &guiPalette->getColor(type); + Palette::GradientType grad = guiPalette->getGradientType(type); - if (ch == '<') - msg = toString("@@|") + - _("This is what the color looks like") + "@@"; - else - msg = "##" + toString(ch) + - _("This is what the color looks like"); + std::string msg; + char ch = guiPalette->getColorChar(type); mPreview->clearRows(); - mPreview->addRow(msg); - setEntry(mRedSlider, mRedText, col >> 16); - setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff); - setEntry(mBlueSlider, mBlueText, col & 0xff); + mPreviewBox->setContent(mTextPreview); + mTextPreview->setFont(gui->getFont()); + mTextPreview->setTextColor( + &guiPalette->getColor(Palette::TEXT)); + mTextPreview->setTextBGColor(NULL); + mTextPreview->setShadow(true); + mTextPreview->setOutline(true); + + switch (type) + { + case Palette::TEXT: + case Palette::SHADOW: + case Palette::OUTLINE: + mTextPreview->setFont(gui->getFont()); + mTextPreview->setOutline(true); + mTextPreview->setShadow(type == Palette::SHADOW); + mTextPreview->setOutline(type == Palette::OUTLINE); + break; + case Palette::BACKGROUND: + case Palette::HIGHLIGHT: + case Palette::SHOP_WARNING: + mTextPreview->setTextBGColor(col); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + mPreview->addRow(rawmsg); + break; + case Palette::CHAT: + case Palette::GM: + case Palette::PLAYER: + case Palette::WHISPER: + case Palette::IS: + case Palette::PARTY: + case Palette::SERVER: + case Palette::LOGGER: + case Palette::HYPERLINK: + mPreviewBox->setContent(mPreview); + mPreview->clearRows(); + + if (ch == '<') + { + msg = toString("@@|") + rawmsg + "@@"; + } + else + { + msg = "##" + toString(ch) + rawmsg; + } + mPreview->addRow(msg); + break; + case Palette::PARTICLE: + case Palette::EXP_INFO: + case Palette::PICKUP_INFO: + case Palette::HIT_PLAYER_MONSTER: + case Palette::HIT_MONSTER_PLAYER: + case Palette::HIT_CRITICAL: + case Palette::MISS: + mTextPreview->setShadow(false); + case Palette::BEING: + case Palette::PC: + case Palette::SELF: + case Palette::GM_NAME: + case Palette::NPC: + case Palette::MONSTER: + mTextPreview->setFont(boldFont); + mTextPreview->setTextColor(col); + break; + } + + if (grad != Palette::STATIC) + { // If nonstatic color, don't display the current, but the committed + // color at the sliders + col = &guiPalette->getCommittedColor(type); + } + + setEntry(mRedSlider, mRedText, col->r); + setEntry(mGreenSlider, mGreenText, col->g); + setEntry(mBlueSlider, mBlueText, col->b); + + mGradTypeSlider->setValue(grad); + updateGradType(); + mGradTypeSlider->setEnabled(true); + + return; + } + + if (event.getId() == "slider_grad") + { + updateGradType(); + updateColor(); return; } @@ -201,16 +301,18 @@ void Setup_Colors::setEntry(gcn::Slider *s, TextField *t, int value) void Setup_Colors::apply() { - textColor->commit(); + guiPalette->commit(); } void Setup_Colors::cancel() { - textColor->rollback(); - int col = textColor->getColorAt(mSelected); - setEntry(mRedSlider, mRedText, col >> 16); - setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff); - setEntry(mBlueSlider, mBlueText, col & 0xff); + guiPalette->rollback(); + Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); + const gcn::Color *col = &guiPalette->getColor(type); + mGradTypeSlider->setValue(guiPalette->getGradientType(type)); + setEntry(mRedSlider, mRedText, col->r); + setEntry(mGreenSlider, mGreenText, col->g); + setEntry(mBlueSlider, mBlueText, col->b); } void Setup_Colors::listen(const TextField *tf) @@ -235,14 +337,46 @@ void Setup_Colors::listen(const TextField *tf) } } +void Setup_Colors::updateGradType() { + if (mSelected == -1) + { + return; + } + + mSelected = mColorBox->getSelected(); + Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); + Palette::GradientType grad = guiPalette->getGradientType(type); + + mGradTypeText->setCaption( + (grad == Palette::STATIC) ? _("Static") : + (grad == Palette::RAINBOW) ? _("Rainbow") : _("Spectrum")); + + bool enable = (grad == Palette::STATIC); + mRedText->setEnabled(enable); + mRedSlider->setEnabled(enable); + mGreenText->setEnabled(enable); + mGreenSlider->setEnabled(enable); + mBlueText->setEnabled(enable); + mBlueSlider->setEnabled(enable); +} + void Setup_Colors::updateColor() { if (mSelected == -1) { return; } - int rgb = static_cast<int>(mRedSlider->getValue()) << 16 | - static_cast<int>(mGreenSlider->getValue()) << 8 | - static_cast<int>(mBlueSlider->getValue()); - textColor->setColorAt(mSelected, rgb); + + Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); + Palette::GradientType grad = + static_cast<Palette::GradientType>(mGradTypeSlider->getValue()); + guiPalette->setGradient(type, grad); + + if (grad == Palette::STATIC) + { + guiPalette->setColor(type, + static_cast<int>(mRedSlider->getValue()), + static_cast<int>(mGreenSlider->getValue()), + static_cast<int>(mBlueSlider->getValue())); + } } diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h index 2831297f..52d3f727 100644 --- a/src/gui/setup_colors.h +++ b/src/gui/setup_colors.h @@ -34,6 +34,8 @@ #include "../guichanfwd.h" +#include "widgets/textpreview.h" + class BrowserBox; class Setup_Colors : public SetupTab, public gcn::ActionListener, @@ -48,12 +50,19 @@ class Setup_Colors : public SetupTab, public gcn::ActionListener, void listen(const TextField *tf); private: + static const std::string rawmsg; + gcn::ListBox *mColorBox; gcn::ScrollArea *mScroll; BrowserBox *mPreview; + TextPreview *mTextPreview; gcn::ScrollArea *mPreviewBox; int mSelected; + gcn::Label *mGradTypeLabel; + gcn::Slider *mGradTypeSlider; + gcn::Label *mGradTypeText; + gcn::Label *mRedLabel; gcn::Slider *mRedSlider; TextField *mRedText; @@ -71,5 +80,6 @@ class Setup_Colors : public SetupTab, public gcn::ActionListener, void setEntry(gcn::Slider *s, TextField *t, int value); void updateColor(); + void updateGradType(); }; #endif diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index 64c97246..aa42c294 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -22,7 +22,7 @@ #include <guichan/font.hpp> #include <guichan/listmodel.hpp> -#include "color.h" +#include "palette.h" #include "shop.h" #include "shoplistbox.h" @@ -63,11 +63,9 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) if (config.getValue("guialpha", 0.8) != mAlpha) mAlpha = config.getValue("guialpha", 0.8); - bool valid; - const int red = (textColor->getColor('H', valid) >> 16) & 0xFF; - const int green = (textColor->getColor('H', valid) >> 8) & 0xFF; - const int blue = textColor->getColor('H', valid) & 0xFF; - const int alpha = (int)(mAlpha * 255.0f); + int alpha = (int)(mAlpha * 255.0f); + const gcn::Color* highlightColor = + &guiPalette->getColor(Palette::HIGHLIGHT, alpha); Graphics *graphics = static_cast<Graphics*>(gcnGraphics); @@ -78,18 +76,27 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) i < mListModel->getNumberOfElements(); ++i, y += mRowHeight) { - gcn::Color backgroundColor = gcn::Color(255, 255, 255, alpha); + gcn::Color temp; + const gcn::Color* backgroundColor = + &guiPalette->getColor(Palette::BACKGROUND, alpha); if (mShopItems && mPlayerMoney < mShopItems->at(i)->getPrice() && mPriceCheck) - if (i == mSelected) - backgroundColor = gcn::Color(145, 0, 0, alpha); + if (i != mSelected) + backgroundColor = &guiPalette->getColor(Palette::SHOP_WARNING, + alpha); else - backgroundColor = gcn::Color(145, 145, 145, alpha); + { + temp = guiPalette->getColor(Palette::SHOP_WARNING, alpha); + temp.r = (temp.r + highlightColor->r) / 2; + temp.g = (temp.g + highlightColor->g) / 2; + temp.b = (temp.g + highlightColor->b) / 2; + backgroundColor = &temp; + } else if (i == mSelected) - backgroundColor = gcn::Color(red, green, blue, alpha); + backgroundColor = highlightColor; - graphics->setColor(backgroundColor); + graphics->setColor(*backgroundColor); graphics->fillRectangle(gcn::Rectangle(0, y, getWidth(), mRowHeight)); if (mShopItems) @@ -100,7 +107,7 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) graphics->drawImage(icon, 1, y); } } - graphics->setColor(gcn::Color(0, 0, 0)); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); graphics->drawText(mListModel->getElementAt(i), ITEM_ICON_SIZE + 5, y + (ITEM_ICON_SIZE - getFont()->getHeight()) / 2); } diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 9ee91166..5f05971d 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -45,6 +45,7 @@ SpeechBubble::SpeechBubble(): mSpeechBox = new TextBox; mSpeechBox->setEditable(false); mSpeechBox->setOpaque(false); + mSpeechBox->setTextColor(&guiPalette->getColor(Palette::CHAT)); mSpeechArea = new ScrollArea(mSpeechBox); @@ -60,11 +61,11 @@ SpeechBubble::SpeechBubble(): setLocationRelativeTo(getParent()); } -void SpeechBubble::setCaption(const std::string &name, const gcn::Color &color) +void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color) { mCaption->setCaption(name); mCaption->adjustSize(); - mCaption->setForegroundColor(color); + mCaption->setForegroundColor(*color); } void SpeechBubble::setText(std::string text, bool showName) diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h index 573e61f0..34e00722 100644 --- a/src/gui/speechbubble.h +++ b/src/gui/speechbubble.h @@ -22,6 +22,7 @@ #ifndef SPEECHBUBBLE_H #define SPEECHBUBBLE_H +#include "palette.h" #include "window.h" class ScrollArea; @@ -33,7 +34,8 @@ class SpeechBubble : public Window SpeechBubble(); void setCaption(const std::string &name, - const gcn::Color &color = 0x000000); + const gcn::Color *color = + &guiPalette->getColor(Palette::TEXT)); void setText(std::string text, bool showName = true); void setLocation(int x, int y); unsigned int getNumRows(); diff --git a/src/gui/table.cpp b/src/gui/table.cpp index 274f9a48..5fc96dbd 100644 --- a/src/gui/table.cpp +++ b/src/gui/table.cpp @@ -23,7 +23,7 @@ #include <guichan/graphics.hpp> #include <guichan/key.hpp> -#include "color.h" +#include "palette.h" #include "table.h" #include "../configuration.h" @@ -273,11 +273,8 @@ void GuiTable::draw(gcn::Graphics* graphics) if (mOpaque) { - const int red = getBackgroundColor().r; - const int green = getBackgroundColor().g; - const int blue = getBackgroundColor().b; - const int alpha = (int)(mAlpha * 255.0f); - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::BACKGROUND, + (int)(mAlpha * 255.0f))); graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); } @@ -324,15 +321,8 @@ void GuiTable::draw(gcn::Graphics* graphics) if (!mLinewiseMode && c == mSelectedColumn && r == mSelectedRow) { - bool valid; - const int red = - (textColor->getColor('H', valid) >> 16) & 0xFF; - const int green = - (textColor->getColor('H', valid) >> 8) & 0xFF; - const int blue = textColor->getColor('H', valid) & 0xFF; - const int alpha = (int)(mAlpha * 127.0f); - - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, + (int)(mAlpha * 127.0f))); graphics->fillRectangle(bounds); } @@ -346,15 +336,8 @@ void GuiTable::draw(gcn::Graphics* graphics) if (mLinewiseMode && r == mSelectedRow) { - bool valid; - const int red = - (textColor->getColor('H', valid) >> 16) & 0xFF; - const int green = - (textColor->getColor('H', valid) >> 8) & 0xFF; - const int blue = textColor->getColor('H', valid) & 0xFF; - const int alpha = (int)(mAlpha * 127.0f); - - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, + (int)(mAlpha * 127.0f))); graphics->fillRectangle(gcn::Rectangle(0, y_offset, x_offset, height)); } diff --git a/src/gui/textbox.cpp b/src/gui/textbox.cpp index a4024de3..10f727e3 100644 --- a/src/gui/textbox.cpp +++ b/src/gui/textbox.cpp @@ -23,10 +23,11 @@ #include <guichan/font.hpp> +#include "palette.h" #include "textbox.h" -TextBox::TextBox(): - gcn::TextBox() +TextBox::TextBox() : + gcn::TextBox(), mTextColor(&guiPalette->getColor(Palette::TEXT)) { setOpaque(false); setFrameSize(0); diff --git a/src/gui/textbox.h b/src/gui/textbox.h index 10a81fc0..5884e11c 100644 --- a/src/gui/textbox.h +++ b/src/gui/textbox.h @@ -39,6 +39,11 @@ class TextBox : public gcn::TextBox */ TextBox(); + inline void setTextColor(const gcn::Color* color) + { + mTextColor = color; + } + /** * Sets the text after wrapping it to the current width of the widget. */ @@ -49,8 +54,18 @@ class TextBox : public gcn::TextBox */ int getMinWidth() { return mMinWidth; } + /** + * Draws the text. + */ + inline void draw(gcn::Graphics *graphics) + { + setForegroundColor(*mTextColor); + gcn::TextBox::draw(graphics); + } + private: int mMinWidth; + const gcn::Color* mTextColor; }; #endif diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h new file mode 100644 index 00000000..0381f766 --- /dev/null +++ b/src/gui/textrenderer.h @@ -0,0 +1,81 @@ +/* + * Text Renderer + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TEXT_RENDERER_H +#define TEXT_RENDERER_H + +#include "graphics.h" +#include "palette.h" + +/** + * Class for text rendering. Used by the TextParticle, the Text and FlashText + * objects and the Preview in the color dialog. + */ +class TextRenderer +{ + public: + /** + * Renders a specified text. + */ + static inline void renderText(gcn::Graphics *graphics, const std::string& + text, int x, int y, gcn::Graphics::Alignment align, + const gcn::Color* color, gcn::Font *font, bool outline = false, + bool shadow = false, int alpha = 255) + { + graphics->setFont(font); + + // Text shadow + if (shadow) + { + graphics->setColor(guiPalette->getColor(Palette::SHADOW, + alpha / 2)); + if (outline) + { + graphics->drawText(text, x + 2, y + 2, align); + } + else + { + graphics->drawText(text, x + 1, y + 1, align); + } + } + + if (outline) { +/* graphics->setColor(guiPalette->getColor(Palette::OUTLINE, + alpha/4)); + // TODO: Reanable when we can draw it nicely in software mode + graphics->drawText(text, x + 2, y + 2, align); + graphics->drawText(text, x + 1, y + 2, align); + graphics->drawText(text, x + 2, y + 1, align);*/ + + // Text outline + graphics->setColor(guiPalette->getColor(Palette::OUTLINE, alpha)); + graphics->drawText(text, x + 1, y, align); + graphics->drawText(text, x - 1, y, align); + graphics->drawText(text, x, y + 1, align); + graphics->drawText(text, x, y - 1, align); + } + + graphics->setColor(*color); + graphics->drawText(text, x, y, align); + } +}; + +#endif diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h index de146087..1cf6c2c8 100644 --- a/src/gui/truetypefont.h +++ b/src/gui/truetypefont.h @@ -26,8 +26,8 @@ #include <string> #include <guichan/font.hpp> -#ifndef __APPLE__ -#include <SDL/SDL_ttf.h> +#ifdef __APPLE__ +#include <SDL_ttf/SDL_ttf.h> #else #include <SDL_ttf.h> #endif diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index c91a8524..b736591c 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -23,8 +23,8 @@ #include "dropdown.h" -#include "../color.h" #include "../listbox.h" +#include "../palette.h" #include "../scrollarea.h" #include "../../configuration.h" @@ -139,27 +139,20 @@ void DropDown::draw(gcn::Graphics* graphics) } } - bool valid; const int alpha = (int)(mAlpha * 255.0f); gcn::Color faceColor = getBaseColor(); faceColor.a = alpha; - gcn::Color highlightColor = textColor->getColor('H', valid); - highlightColor.a = alpha; + const gcn::Color* highlightColor = &guiPalette->getColor(Palette::HIGHLIGHT, + alpha); gcn::Color shadowColor = faceColor - 0x303030; shadowColor.a = alpha; if (mOpaque) { - int red = getBackgroundColor().r; - int green = getBackgroundColor().g; - int blue = getBackgroundColor().b; - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::BACKGROUND, alpha)); graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), h)); - red = getForegroundColor().r; - green = getForegroundColor().g; - blue = getForegroundColor().b; - graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->setColor(guiPalette->getColor(Palette::TEXT, alpha)); } graphics->setFont(getFont()); @@ -171,7 +164,7 @@ void DropDown::draw(gcn::Graphics* graphics) if (isFocused()) { - graphics->setColor(highlightColor); + graphics->setColor(*highlightColor); graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth() - h, h)); } @@ -183,7 +176,7 @@ void DropDown::draw(gcn::Graphics* graphics) // Draw two lines separating the ListBox with selected // element view. - graphics->setColor(highlightColor); + graphics->setColor(*highlightColor); graphics->drawLine(0, h, getWidth(), h); graphics->setColor(shadowColor); graphics->drawLine(0, h + 1, getWidth(), h + 1); diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp new file mode 100644 index 00000000..4fcaa4a7 --- /dev/null +++ b/src/gui/widgets/textpreview.cpp @@ -0,0 +1,55 @@ +/* + * The Mana World + * Copyright (C) 2006 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <typeinfo> + +#include "textpreview.h" + +#include "../gui.h" +#include "../palette.h" +#include "../textrenderer.h" +#include "../truetypefont.h" + +TextPreview::TextPreview(const std::string* text) +{ + mText = text; + mFont = gui->getFont(); + mTextColor = &guiPalette->getColor(Palette::TEXT); + mTextBGColor = NULL; + mBGColor = &guiPalette->getColor(Palette::BACKGROUND); +} + +void TextPreview::draw(gcn::Graphics* graphics) +{ + graphics->setColor(*mBGColor); + graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); + + if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont)) { + TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont); + graphics->setColor(*mTextBGColor); + int x = font->getWidth(*mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0); + int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0); + graphics->fillRectangle(gcn::Rectangle(1, 1, x, y)); + } + + TextRenderer::renderText(graphics, *mText, 2, 2, gcn::Graphics::LEFT, + mTextColor, mFont, mOutline, mShadow); +} diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h new file mode 100644 index 00000000..1c1fa1e4 --- /dev/null +++ b/src/gui/widgets/textpreview.h @@ -0,0 +1,114 @@ +/* + * The Mana World + * Copyright (C) 2006 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TEXTPREVIEW_H +#define TEXTPREVIEW_H + +#include <guichan/color.hpp> +#include <guichan/font.hpp> +#include <guichan/widget.hpp> + +/** + * Preview widget for particle colors, etc. + */ +class TextPreview : public gcn::Widget { + public: + TextPreview(const std::string* text); + + /** + * Sets the color the text is printed in. + * + * @param color the color to set + */ + inline void setTextColor(const gcn::Color* color) + { + mTextColor = color; + } + + /** + * Sets the color the text background is drawn in. This is only the + * rectangle directly behind the text, not to full widget. + * + * @param color the color to set + */ + inline void setTextBGColor(const gcn::Color* color) + { + mTextBGColor = color; + } + + /** + * Sets the background color of the widget. + * + * @param color the color to set + */ + inline void setBGColor(const gcn::Color* color) + { + mBGColor = color; + } + + /** + * Sets the font to render the text in. + * + * @param font the font to use. + */ + inline void setFont(gcn::Font *font) + { + mFont = font; + } + + /** + * Sets whether to use a shadow while rendering. + * + * @param shadow true, if a shadow is wanted, false else + */ + inline void setShadow(bool shadow) + { + mShadow = shadow; + } + + /** + * Sets whether to use an outline while rendering. + * + * @param outline true, if an outline is wanted, false else + */ + inline void setOutline(bool outline) + { + mOutline = outline; + } + + /** + * Widget's draw method. Does the actual job. + * + * @param graphics graphics to draw into + */ + void draw(gcn::Graphics *graphics); + + private: + gcn::Font *mFont; + const std::string* mText; + const gcn::Color* mTextColor; + const gcn::Color* mBGColor; + const gcn::Color* mTextBGColor; + bool mShadow; + bool mOutline; +}; + +#endif diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 296bc28c..30ff9c35 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -38,6 +38,7 @@ #include "gui/gui.h" #include "gui/ministatus.h" +#include "gui/palette.h" #include "gui/storagewindow.h" #include "net/messageout.h" @@ -212,7 +213,9 @@ void LocalPlayer::logic() void LocalPlayer::setGM() { mIsGM = !mIsGM; - mNameColor = mIsGM ? 0x009000: 0x202020; + mNameColor = mIsGM ? + &guiPalette->getColor(Palette::GM) : + &guiPalette->getColor(Palette::PLAYER); setName(getName()); config.setValue(getName() + "GMassert", mIsGM); } @@ -614,10 +617,9 @@ void LocalPlayer::setXp(int xp) const std::string text = toString(xp - mXp) + " xp"; // Show XP number - particleEngine->addTextRiseFadeOutEffect(text, - gui->getInfoParticleFont(), - mPx + 16, mPy - 16, - 255, 255, 0, true); + particleEngine->addTextRiseFadeOutEffect(text, mPx + 16, mPy - 16, + &guiPalette->getColor(Palette::EXP_INFO), + gui->getInfoParticleFont(), true); } mXp = xp; } @@ -627,10 +629,9 @@ void LocalPlayer::pickedUp(std::string item) if (mMap) { // Show pickup notification - particleEngine->addTextRiseFadeOutEffect(item, - gui->getInfoParticleFont (), - mPx + 16, mPy - 16, - 40, 220, 40, true); + particleEngine->addTextRiseFadeOutEffect(item, mPx + 16, mPy - 16, + &guiPalette->getColor(Palette::PICKUP_INFO), + gui->getInfoParticleFont (), true); } } diff --git a/src/main.cpp b/src/main.cpp index 306514e4..dddf53d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,15 +51,16 @@ #include "player_relations.h" #include "serverinfo.h" #include "sound.h" +#include "statuseffect.h" #include "units.h" #include "gui/button.h" #include "gui/char_server.h" #include "gui/char_select.h" -#include "gui/color.h" #include "gui/gui.h" #include "gui/login.h" #include "gui/ok_dialog.h" +#include "gui/palette.h" #include "gui/progressbar.h" #include "gui/register.h" #include "gui/sdlinput.h" @@ -134,7 +135,7 @@ CharServerHandler charServerHandler; LoginData loginData; LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1); -Color *textColor; +Palette *guiPalette; // This anonymous namespace hides whatever is inside from other modules. namespace { @@ -482,14 +483,13 @@ void exit_engine() // Shutdown sound sound.close(); - Being::cleanup(); - // Unload XML databases ColorDB::unload(); EmoteDB::unload(); ItemDB::unload(); MonsterDB::unload(); NPCDB::unload(); + StatusEffect::unload(); ResourceManager::deleteInstance(); delete logger; @@ -774,7 +774,7 @@ int main(int argc, char *argv[]) unsigned int oldstate = !state; // We start with a status change. // Needs to be created in main, as the updater uses it - textColor = new Color; + guiPalette = new Palette; Game *game = NULL; Window *currentDialog = NULL; @@ -948,7 +948,8 @@ int main(int argc, char *argv[]) MonsterDB::load(); NPCDB::load(); EmoteDB::load(); - Being::load(); // Hairstyles and emotions + StatusEffect::load(); + Being::load(); // Hairstyles state = CHAR_CONNECT_STATE; break; @@ -1110,7 +1111,7 @@ int main(int argc, char *argv[]) usleep(50000); } - delete textColor; + delete guiPalette; #ifdef PACKAGE_VERSION delete versionLabel; #endif diff --git a/src/monster.cpp b/src/monster.cpp index 89d0953d..7dc08238 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -27,6 +27,8 @@ #include "sound.h" #include "text.h" +#include "gui/palette.h" + #include "resources/monsterdb.h" #include "resources/monsterinfo.h" @@ -71,7 +73,7 @@ Monster::Monster(int id, Uint16 job, Map *map): } } - mNameColor = 0xff2020; + mNameColor = &guiPalette->getColor(Palette::MONSTER); } Monster::~Monster() @@ -195,7 +197,8 @@ void Monster::showName(bool show) { mText = new Text(getInfo().getName(), mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET - getHeight(), - gcn::Graphics::CENTER, gcn::Color(255, 64, 64)); + gcn::Graphics::CENTER, + &guiPalette->getColor(Palette::MONSTER)); } else { diff --git a/src/npc.cpp b/src/npc.cpp index 5a4f9507..630316e0 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -26,6 +26,7 @@ #include "text.h" #include "gui/npc_text.h" +#include "gui/palette.h" #include "net/messageout.h" #include "net/protocol.h" @@ -71,7 +72,7 @@ NPC::NPC(int id, Uint16 job, Map *map, Network *network): } mName = 0; - mNameColor = 0x21bbbb; + mNameColor = &guiPalette->getColor(Palette::NPC); } NPC::~NPC() @@ -85,7 +86,8 @@ void NPC::setName(const std::string &name) delete mName; mName = new Text(displayName, mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET, - gcn::Graphics::CENTER, gcn::Color(200, 200, 255)); + gcn::Graphics::CENTER, + &guiPalette->getColor(Palette::NPC)); Being::setName(displayName + " (NPC)"); } diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index e7e7b204..0ee2bc50 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -26,12 +26,12 @@ #include "resources/image.h" +#ifdef USE_OPENGL + #ifdef __APPLE__ #include <OpenGL/OpenGL.h> #endif -#ifdef USE_OPENGL - #ifndef GL_TEXTURE_RECTANGLE_ARB #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 diff --git a/src/particle.cpp b/src/particle.cpp index 6dc45a08..82c163c6 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -324,12 +324,10 @@ Particle *Particle::addEffect(const std::string &particleEffectFile, return newParticle; } -Particle *Particle::addTextSplashEffect(const std::string &text, - int colorR, int colorG, int colorB, - gcn::Font *font, int x, int y, bool outline) +Particle *Particle::addTextSplashEffect(const std::string &text, int x, int y, + const gcn::Color *color, gcn::Font *font, bool outline) { - Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB, - font, outline); + Particle *newParticle = new TextParticle(mMap, text, color, font, outline); newParticle->moveTo(x, y); newParticle->setVelocity(((rand() % 100) - 50) / 200.0f, // X ((rand() % 100) - 50) / 200.0f, // Y @@ -345,13 +343,8 @@ Particle *Particle::addTextSplashEffect(const std::string &text, } Particle *Particle::addTextRiseFadeOutEffect(const std::string &text, - gcn::Font *font, - int x, int y, - int colorR, int colorG, - int colorB, bool outline) -{ - Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB, - font, 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); newParticle->setGravity(0.0015f); diff --git a/src/particle.h b/src/particle.h index b4c80194..3584c4fc 100644 --- a/src/particle.h +++ b/src/particle.h @@ -105,19 +105,17 @@ class Particle : public Sprite /** * Creates a standalone text particle. */ - Particle *addTextSplashEffect(const std::string &text, - int colorR, int colorG, int colorB, - gcn::Font *font, int x, int y, - bool outline = false); + Particle *addTextSplashEffect(const std::string &text, int x, int y, + const gcn::Color *color, gcn::Font *font, + bool outline = false); /** * Creates a standalone text particle. */ Particle *addTextRiseFadeOutEffect(const std::string &text, - gcn::Font *font, - int x, int y, int colorR = 255, - int colorG = 255, int colorB = 255, - bool outline = false); + int x, int y, const gcn::Color *color, gcn::Font *font, + bool outline = false); + /** * Adds an emitter to the particle. */ diff --git a/src/player.cpp b/src/player.cpp index e1928280..8668ac58 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -21,10 +21,13 @@ #include "animatedsprite.h" #include "game.h" +#include "localplayer.h" #include "particle.h" #include "player.h" #include "text.h" +#include "gui/palette.h" + #include "resources/colordb.h" #include "resources/itemdb.h" @@ -50,17 +53,19 @@ void Player::setName(const std::string &name) { if (mIsGM) { - mNameColor = 0x009000; + mNameColor = &guiPalette->getColor(Palette::GM); mName = new FlashText("(GM) " + name, mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET, gcn::Graphics::CENTER, - gcn::Color(0, 255, 0)); + &guiPalette->getColor(Palette::GM)); } else { - mNameColor = 0x202020; + mNameColor = &guiPalette->getColor(Palette::PLAYER); mName = new FlashText(name, mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET, gcn::Graphics::CENTER, - gcn::Color(255, 255, 255)); + (this == player_node) ? + &guiPalette->getColor(Palette::SELF) : + &guiPalette->getColor(Palette::PC)); } Being::setName(name); } diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp index 5e9a146c..5bc8407a 100644 --- a/src/resources/emotedb.cpp +++ b/src/resources/emotedb.cpp @@ -21,6 +21,7 @@ #include "emotedb.h" +#include "../animatedsprite.h" #include "../log.h" #include "../utils/xml.h" @@ -41,9 +42,8 @@ void EmoteDB::load() mLastEmote = 0; EmoteSprite *unknownSprite = new EmoteSprite; - unknownSprite->sprite = "error.xml"; + unknownSprite->sprite = AnimatedSprite::load("error.xml"); unknownSprite->name = "unknown"; - unknownSprite->variant = 0; mUnknown.sprites.push_back(unknownSprite); logger->log("Initializing emote database..."); @@ -77,8 +77,10 @@ void EmoteDB::load() if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) { EmoteSprite *currentSprite = new EmoteSprite; - currentSprite->sprite = (const char*) spriteNode->xmlChildrenNode->content; - currentSprite->variant = XML::getProperty(spriteNode, "variant", 0); + std::string file = "graphics/sprites/" + (std::string) + (const char*) spriteNode->xmlChildrenNode->content; + currentSprite->sprite = AnimatedSprite::load(file, + XML::getProperty(spriteNode, "variant", 0)); currentInfo->sprites.push_back(currentSprite); } else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) @@ -102,6 +104,7 @@ void EmoteDB::unload() { while (!i->second->sprites.empty()) { + delete i->second->sprites.front()->sprite; delete i->second->sprites.front(); i->second->sprites.pop_front(); } @@ -112,6 +115,7 @@ void EmoteDB::unload() while (!mUnknown.sprites.empty()) { + delete mUnknown.sprites.front()->sprite; delete mUnknown.sprites.front(); mUnknown.sprites.pop_front(); } @@ -119,21 +123,27 @@ void EmoteDB::unload() mLoaded = false; } -const EmoteInfo& EmoteDB::get(int id) +const EmoteInfo *EmoteDB::get(int id) { EmoteInfosIterator i = mEmoteInfos.find(id); if (i == mEmoteInfos.end()) { logger->log("EmoteDB: Warning, unknown emote ID %d requested", id); - return mUnknown; + return &mUnknown; } else { - return *(i->second); + return i->second; } } +const AnimatedSprite* EmoteDB::getAnimation(int id) +{ + const EmoteInfo *info = get(id); + return info->sprites.front()->sprite; +} + const int& EmoteDB::getLast() { return mLastEmote; diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h index ad21722a..691881c8 100644 --- a/src/resources/emotedb.h +++ b/src/resources/emotedb.h @@ -26,11 +26,12 @@ #include <map> #include <string> +class AnimatedSprite; + struct EmoteSprite { - std::string sprite; + const AnimatedSprite *sprite; std::string name; - int variant; }; struct EmoteInfo @@ -50,7 +51,9 @@ namespace EmoteDB void unload(); - const EmoteInfo& get(int id); + const EmoteInfo *get(int id); + + const AnimatedSprite *getAnimation(int id); const int& getLast(); diff --git a/src/statuseffect.cpp b/src/statuseffect.cpp index c0d689f0..70e8d59f 100644 --- a/src/statuseffect.cpp +++ b/src/statuseffect.cpp @@ -92,7 +92,6 @@ static std::map<int, int> blockEffectIndexMap; int StatusEffect::blockEffectIndexToEffectIndex(int blockIndex) { - load(); if (blockEffectIndexMap.find(blockIndex) == blockEffectIndexMap.end()) return -1; return blockEffectIndexMap[blockIndex]; @@ -100,27 +99,16 @@ int StatusEffect::blockEffectIndexToEffectIndex(int blockIndex) StatusEffect *StatusEffect::getStatusEffect(int index, bool enabling) { - load(); return statusEffects[enabling][index]; } StatusEffect *StatusEffect::getStunEffect(int index, bool enabling) { - load(); return stunEffects[enabling][index]; } -static bool status_effects_loaded = false; - - - void StatusEffect::load() { - if (status_effects_loaded) - return; - - status_effects_loaded = true; - XML::Document doc(STATUS_EFFECTS_FILE); xmlNodePtr rootNode = doc.rootNode(); @@ -168,3 +156,19 @@ void StatusEffect::load() } } } + +void unloadMap(std::map<int, StatusEffect *> map) +{ + std::map<int, StatusEffect *>::iterator it; + + for (it = map.begin(); it != map.end(); it++) + delete (*it).second; +} + +void StatusEffect::unload() +{ + unloadMap(statusEffects[0]); + unloadMap(statusEffects[1]); + unloadMap(stunEffects[0]); + unloadMap(stunEffects[1]); +}
\ No newline at end of file diff --git a/src/statuseffect.h b/src/statuseffect.h index 16fed69a..f1af93d2 100644 --- a/src/statuseffect.h +++ b/src/statuseffect.h @@ -94,9 +94,11 @@ public: */ static int blockEffectIndexToEffectIndex(int blocKIndex); -private: static void load(); + static void unload(); +private: + std::string mMessage; std::string mSFXEffect; std::string mParticleEffect; diff --git a/src/text.cpp b/src/text.cpp index cb4587d3..b0be25bf 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -30,6 +30,8 @@ #include "resources/image.h" #include "gui/gui.h" +#include "gui/palette.h" +#include "gui/textrenderer.h" int Text::mInstances = 0; ImageRect Text::mBubble; @@ -37,7 +39,7 @@ Image *Text::mBubbleArrow; Text::Text(const std::string &text, int x, int y, gcn::Graphics::Alignment alignment, - gcn::Color color, bool isSpeech) : + const gcn::Color* color, bool isSpeech) : mText(text), mColor(color), mIsSpeech(isSpeech) @@ -129,42 +131,14 @@ void Text::draw(gcn::Graphics *graphics, int xOff, int yOff) */ } - // Text shadow - graphics->setColor(gcn::Color(0, 0, 0)); - graphics->drawText(mText, mX - xOff + 1, mY - yOff + 1, - gcn::Graphics::LEFT); - - if (!mIsSpeech) { - graphics->setColor(gcn::Color(0, 0, 0, 64)); - /* - // TODO: Reanable when we can draw it nicely in software mode - graphics->drawText(mText, mX - xOff + 2, mY - yOff + 2, - gcn::Graphics::LEFT); - graphics->drawText(mText, mX - xOff + 1, mY - yOff + 2, - gcn::Graphics::LEFT); - graphics->drawText(mText, mX - xOff + 2, mY - yOff + 1, - gcn::Graphics::LEFT); - */ - - // Text outline - graphics->setColor(gcn::Color(0, 0, 0)); - graphics->drawText(mText, mX - xOff + 1, mY - yOff, - gcn::Graphics::LEFT); - graphics->drawText(mText, mX - xOff - 1, mY - yOff, - gcn::Graphics::LEFT); - graphics->drawText(mText, mX - xOff, mY - yOff + 1, - gcn::Graphics::LEFT); - graphics->drawText(mText, mX - xOff, mY - yOff - 1, - gcn::Graphics::LEFT); - } - - graphics->setColor(mColor); - graphics->drawText(mText, mX - xOff, mY - yOff, gcn::Graphics::LEFT); + TextRenderer::renderText(graphics, mText, + mX - xOff, mY - yOff, gcn::Graphics::LEFT, + mColor, boldFont, !mIsSpeech, true); } FlashText::FlashText(const std::string &text, int x, int y, gcn::Graphics::Alignment alignment, - gcn::Color color) : + const gcn::Color *color) : Text(text, x, y, alignment, color), mTime(0) { @@ -40,7 +40,7 @@ class Text */ Text(const std::string &text, int x, int y, gcn::Graphics::Alignment alignment, - gcn::Color color, bool isSpeech = false); + const gcn::Color *color, bool isSpeech = false); /** * Destructor. The text is removed from the screen. @@ -65,7 +65,7 @@ class Text int mXOffset; /**< The offset of mX from the desired x. */ static int mInstances; /**< Instances of text. */ std::string mText; /**< The text to display. */ - gcn::Color mColor; /**< The color of the text. */ + const gcn::Color *mColor; /**< The color of the text. */ bool mIsSpeech; /**< Is this text a speech bubble? */ protected: @@ -78,7 +78,7 @@ class FlashText : public Text public: FlashText(const std::string &text, int x, int y, gcn::Graphics::Alignment alignment, - gcn::Color color); + const gcn::Color* color); /** * Remove the text from the screen diff --git a/src/textparticle.cpp b/src/textparticle.cpp index 3494b97f..792b6bea 100644 --- a/src/textparticle.cpp +++ b/src/textparticle.cpp @@ -21,19 +21,17 @@ #include <guichan/color.hpp> -#include "graphics.h" #include "textparticle.h" -#include <SDL/SDL_ttf.h> + +#include "gui/textrenderer.h" TextParticle::TextParticle(Map *map, const std::string &text, - int colorR, int colorG, int colorB, + const gcn::Color* color, gcn::Font *font, bool outline): Particle(map), mText(text), mTextFont(font), - mColorR(colorR), - mColorG(colorG), - mColorB(colorB), + mColor(color), mOutline(outline) { } @@ -60,24 +58,7 @@ void TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const alpha /= mFadeIn; } - graphics->setFont(mTextFont); - if (mOutline) - { - graphics->setColor(gcn::Color(0, 0, 0, (int)(alpha/4))); - // Text outline - graphics->setColor(gcn::Color(0, 0, 0, (int)alpha)); - graphics->drawText(mText, screenX + 1, screenY, - gcn::Graphics::CENTER); - - graphics->drawText(mText, screenX - 1, screenY, - gcn::Graphics::CENTER); - - graphics->drawText(mText, screenX, screenY + 1, - gcn::Graphics::CENTER); - - graphics->drawText(mText, screenX, screenY - 1, - gcn::Graphics::CENTER); - } - graphics->setColor(gcn::Color(mColorR, mColorG, mColorB, (int)alpha)); - graphics->drawText(mText, screenX, screenY, gcn::Graphics::CENTER); + TextRenderer::renderText(graphics, mText, + screenX, screenY, gcn::Graphics::CENTER, + mColor, mTextFont, mOutline, false, (int)alpha); } diff --git a/src/textparticle.h b/src/textparticle.h index d72df138..8b7d3e01 100644 --- a/src/textparticle.h +++ b/src/textparticle.h @@ -32,7 +32,7 @@ class TextParticle : public Particle * Constructor. */ TextParticle(Map *map, const std::string &text, - int colorR, int colorG, int colorB, + const gcn::Color* color, gcn::Font *font, bool outline = false); /** @@ -47,9 +47,8 @@ class TextParticle : public Particle private: std::string mText; /**< Text of the particle. */ gcn::Font *mTextFont; /**< Font used for drawing the text. */ - int mColorR, mColorG, mColorB; /**< Color used for drawing the text. */ - bool mOutline; /**< Make the text readable - draw it the way - a Text is usually drawn: with outline */ + const gcn::Color* mColor; /**< Color used for drawing the text. */ + bool mOutline; /**< Make the text better readable */ }; #endif diff --git a/src/units.cpp b/src/units.cpp index 4f8b95f0..7e8d8e6a 100644 --- a/src/units.cpp +++ b/src/units.cpp @@ -164,8 +164,8 @@ std::string formatUnit(int value, int type) struct UnitLevel ul; double amount = ud.conversion * value; - // Shortcut for 0 - if (value == 0) { + // Shortcut for 0; do the same for values less than 0 (for now) + if (value <= 0) { ul = ud.levels[0]; return strprintf("0%s", ul.symbol.c_str()); } else { @@ -126,8 +126,6 @@ <Unit filename="src\gui\chatinput.h" /> <Unit filename="src\gui\checkbox.cpp" /> <Unit filename="src\gui\checkbox.h" /> - <Unit filename="src\gui\color.cpp" /> - <Unit filename="src\gui\color.h" /> <Unit filename="src\gui\confirm_dialog.cpp" /> <Unit filename="src\gui\confirm_dialog.h" /> <Unit filename="src\gui\connection.cpp" /> @@ -185,6 +183,8 @@ <Unit filename="src\gui\npcstringdialog.h" /> <Unit filename="src\gui\ok_dialog.cpp" /> <Unit filename="src\gui\ok_dialog.h" /> + <Unit filename="src\gui\palette.cpp" /> + <Unit filename="src\gui\palette.h" /> <Unit filename="src\gui\passwordfield.cpp" /> <Unit filename="src\gui\passwordfield.h" /> <Unit filename="src\gui\playerbox.cpp" /> @@ -266,6 +266,8 @@ <Unit filename="src\gui\widgets\tab.h" /> <Unit filename="src\gui\widgets\tabbedarea.cpp" /> <Unit filename="src\gui\widgets\tabbedarea.h" /> + <Unit filename="src\gui\widgets\textpreview.cpp" /> + <Unit filename="src\gui\widgets\textpreview.h" /> <Unit filename="src\gui\window.cpp" /> <Unit filename="src\gui\window.h" /> <Unit filename="src\gui\windowcontainer.cpp" /> |