diff options
52 files changed, 468 insertions, 230 deletions
@@ -1,4 +1,4 @@ -1.0.0 (31 March 2010) +1.0.0 (...) - The Mana World client is now called the Mana client - Added support for branding the client differently via command line parameter - Added support for ManaServ and eAthena (TMW version) from the same binary diff --git a/configure.ac b/configure.ac index b1ceceec..058fc0a6 100755 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.59) -AC_INIT([Mana], [1.0.0-beta], [dev@manasource.org], [mana]) +AC_INIT([Mana], [1.0.0-beta2], [dev@manasource.org], [mana]) AM_INIT_AUTOMAKE([1.9]) AC_CONFIG_HEADERS([config.h:config.h.in]) AC_LANG_CPLUSPLUS @@ -141,6 +141,7 @@ data/fonts/Makefile data/graphics/Makefile data/graphics/gui/Makefile data/graphics/images/Makefile +data/graphics/sprites/Makefile data/help/Makefile data/icons/Makefile docs/Makefile diff --git a/data/graphics/CMakeLists.txt b/data/graphics/CMakeLists.txt index d7e78c30..a46ccfd0 100644 --- a/data/graphics/CMakeLists.txt +++ b/data/graphics/CMakeLists.txt @@ -1,5 +1,6 @@ ADD_SUBDIRECTORY(gui) ADD_SUBDIRECTORY(images) +ADD_SUBDIRECTORY(sprites) SET (FILES target-cursor-in-range-l.png @@ -8,4 +9,4 @@ SET (FILES target-cursor-normal-l.png target-cursor-normal-m.png target-cursor-normal-s.png - )
\ No newline at end of file + ) diff --git a/data/graphics/Makefile.am b/data/graphics/Makefile.am index 6a4d65d8..d2f93f58 100644 --- a/data/graphics/Makefile.am +++ b/data/graphics/Makefile.am @@ -9,8 +9,8 @@ graphics_DATA = \ target-cursor-normal-m.png \ target-cursor-normal-s.png -SUBDIRS = gui images - -EXTRA_DIST = \ - $(graphics_DATA) \ +EXTRA_DIST = \ + $(graphics_DATA) \ CMakeLists.txt + +SUBDIRS = gui images sprites diff --git a/data/graphics/images/CMakeLists.txt b/data/graphics/images/CMakeLists.txt index 5181b4e1..6694f254 100644 --- a/data/graphics/images/CMakeLists.txt +++ b/data/graphics/images/CMakeLists.txt @@ -1,5 +1,4 @@ SET(FILES - error.png login_wallpaper.png ) diff --git a/data/graphics/images/Makefile.am b/data/graphics/images/Makefile.am index 0bc2a5cd..20ea859f 100644 --- a/data/graphics/images/Makefile.am +++ b/data/graphics/images/Makefile.am @@ -1,9 +1,8 @@ imagesdir = $(pkgdatadir)/data/graphics/images images_DATA = \ - error.png \ login_wallpaper.png EXTRA_DIST = \ - $(images_DATA) \ + $(images_DATA) \ CMakeLists.txt diff --git a/data/graphics/sprites/CMakeLists.txt b/data/graphics/sprites/CMakeLists.txt new file mode 100644 index 00000000..1d98772d --- /dev/null +++ b/data/graphics/sprites/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(FILES + error.png + error.xml + ) + +INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/graphics/sprits) diff --git a/data/graphics/sprites/Makefile.am b/data/graphics/sprites/Makefile.am new file mode 100644 index 00000000..249ca5cd --- /dev/null +++ b/data/graphics/sprites/Makefile.am @@ -0,0 +1,9 @@ +spritesdir = $(pkgdatadir)/data/graphics/sprites + +sprites_DATA = \ + error.png \ + error.xml + +EXTRA_DIST = \ + $(sprites_DATA) \ + CMakeLists.txt diff --git a/data/graphics/images/error.png b/data/graphics/sprites/error.png Binary files differindex 6fd7c1a8..6fd7c1a8 100644 --- a/data/graphics/images/error.png +++ b/data/graphics/sprites/error.png diff --git a/data/graphics/sprites/error.xml b/data/graphics/sprites/error.xml new file mode 100644 index 00000000..3504bd01 --- /dev/null +++ b/data/graphics/sprites/error.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<sprite> + <imageset name="base" src="graphics/sprites/error.png" width="29" height="9" /> + + <action name="default" imageset="base"> + <animation direction="default"> + <frame index="0" /> + </animation> + </action> +</sprite>
\ No newline at end of file diff --git a/packaging/windows/setup.nsi b/packaging/windows/setup.nsi index d768821e..1b5dc97c 100644 --- a/packaging/windows/setup.nsi +++ b/packaging/windows/setup.nsi @@ -189,6 +189,7 @@ Section "Core files (required)" SecCore CreateDirectory "$INSTDIR\data\icons" CreateDirectory "$INSTDIR\data\graphics\gui" CreateDirectory "$INSTDIR\data\graphics\images" + CreateDirectory "$INSTDIR\data\graphics\sprites" CreateDirectory "$INSTDIR\docs" SetOverwrite ifnewer @@ -209,6 +210,9 @@ Section "Core files (required)" SecCore File "${SRCDIR}\data\graphics\gui\*.xml" SetOutPath "$INSTDIR\data\graphics\images" File /x minimap_*.png ${SRCDIR}\data\graphics\images\*.png + SetOutPath "$INSTDIR\data\graphics\sprites" + File "${SRCDIR}\data\graphics\sprites\*.png" + File "${SRCDIR}\data\graphics\sprites\*.xml" SetOutPath "$INSTDIR\data\help" File "${SRCDIR}\data\help\*.txt" SetOutPath "$INSTDIR\data\icons\" diff --git a/po/POTFILES.in b/po/POTFILES.in index 738dd8a3..e2fbe68b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -23,11 +23,11 @@ src/gui/itemamount.cpp src/gui/itempopup.cpp src/gui/login.cpp src/gui/minimap.cpp +src/gui/ministatus.cpp src/gui/npcdialog.cpp src/gui/npcpostdialog.cpp src/gui/okdialog.cpp src/gui/outfitwindow.cpp -src/gui/palette.cpp src/gui/popupmenu.cpp src/gui/quitdialog.cpp src/gui/recorder.cpp @@ -48,11 +48,11 @@ src/gui/skilldialog.cpp src/gui/socialwindow.cpp src/gui/specialswindow.cpp src/gui/statuswindow.cpp -src/gui/storagewindow.cpp src/gui/textdialog.cpp src/gui/trade.cpp src/gui/unregisterdialog.cpp src/gui/updatewindow.cpp +src/gui/userpalette.cpp src/gui/widgets/channeltab.cpp src/gui/widgets/chattab.cpp src/gui/widgets/whispertab.cpp @@ -62,33 +62,34 @@ src/keyboardconfig.cpp src/localplayer.cpp src/log.h src/main.cpp -src/net/ea/adminhandler.cpp -src/net/ea/buysellhandler.cpp -src/net/ea/charserverhandler.cpp -src/net/ea/chathandler.cpp -src/net/ea/gamehandler.cpp -src/net/ea/generalhandler.cpp -src/net/ea/gui/guildtab.cpp -src/net/ea/guildhandler.cpp -src/net/ea/gui/partytab.cpp -src/net/ea/inventoryhandler.cpp -src/net/ea/loginhandler.cpp -src/net/ea/network.cpp -src/net/ea/partyhandler.cpp -src/net/ea/playerhandler.cpp -src/net/ea/specialhandler.cpp -src/net/ea/tradehandler.cpp src/net/manaserv/beinghandler.cpp src/net/manaserv/charhandler.cpp src/net/manaserv/chathandler.cpp -src/net/manaserv/generalhandler.cpp src/net/manaserv/guildhandler.cpp src/net/manaserv/loginhandler.cpp src/net/manaserv/partyhandler.cpp src/net/manaserv/playerhandler.cpp +src/net/manaserv/stats.cpp src/net/manaserv/tradehandler.cpp +src/net/tmwa/adminhandler.cpp +src/net/tmwa/buysellhandler.cpp +src/net/tmwa/charserverhandler.cpp +src/net/tmwa/chathandler.cpp +src/net/tmwa/gamehandler.cpp +src/net/tmwa/generalhandler.cpp +src/net/tmwa/gui/guildtab.cpp +src/net/tmwa/guildhandler.cpp +src/net/tmwa/gui/partytab.cpp +src/net/tmwa/inventoryhandler.cpp +src/net/tmwa/loginhandler.cpp +src/net/tmwa/network.cpp +src/net/tmwa/partyhandler.cpp +src/net/tmwa/playerhandler.cpp +src/net/tmwa/specialhandler.cpp +src/net/tmwa/tradehandler.cpp src/playerrelations.cpp src/resources/itemdb.cpp src/resources/monsterdb.cpp +src/resources/monsterinfo.cpp src/utils/gettext.h src/utils/stringutils.h diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp index a7821699..1104d810 100644 --- a/src/actorsprite.cpp +++ b/src/actorsprite.cpp @@ -43,6 +43,7 @@ ImageSet *ActorSprite::targetCursorImages[2][NUM_TC]; SimpleAnimation *ActorSprite::targetCursor[2][NUM_TC]; +bool ActorSprite::loaded = false; ActorSprite::ActorSprite(int id): mId(id), @@ -345,12 +346,21 @@ void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display, void ActorSprite::load() { + if (loaded) + unload(); + initTargetCursor(); + + loaded = true; } void ActorSprite::unload() { + if (!loaded) + return; + cleanupTargetCursors(); + loaded = false; } static const char *cursorType(int type) diff --git a/src/actorsprite.h b/src/actorsprite.h index 6c5885e6..e218ef74 100644 --- a/src/actorsprite.h +++ b/src/actorsprite.h @@ -223,6 +223,8 @@ private: /** Animated target cursors. */ static SimpleAnimation *targetCursor[NUM_TCT][NUM_TC]; + static bool loaded; + /** Target cursor being used */ SimpleAnimation *mUsedTargetCursor; }; diff --git a/src/client.cpp b/src/client.cpp index 323d5b49..35292d22 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -433,6 +433,14 @@ Client::~Client() SDL_RemoveTimer(mLogicCounterId); SDL_RemoveTimer(mSecondsCounterId); + // Unload XML databases + ColorDB::unload(); + EmoteDB::unload(); + ItemDB::unload(); + MonsterDB::unload(); + NPCDB::unload(); + StatusEffect::unload(); + // Before config.write() since it writes the shortcuts to the config delete itemShortcut; delete emoteShortcut; @@ -586,19 +594,6 @@ int Client::exec() { delete game; game = 0; - - if (mState != STATE_CHANGE_MAP) - { - // Unload XML databases - ColorDB::unload(); - EmoteDB::unload(); - ItemDB::unload(); - MonsterDB::unload(); - NPCDB::unload(); - StatusEffect::unload(); - - ActorSprite::unload(); - } } mOldState = mState; @@ -973,6 +968,7 @@ int Client::exec() case STATE_ERROR: logger->log("State: ERROR"); + logger->log("Error: %s\n", errorMessage.c_str()); mCurrentDialog = new OkDialog(_("Error"), errorMessage); mCurrentDialog->addActionListener(&errorListener); mCurrentDialog = NULL; // OkDialog deletes itself @@ -1159,6 +1155,10 @@ void Client::initUpdatesDir() mUpdateHost = config.getValue("updatehost", ""); } + // Don't go out of range int he next check + if (mUpdateHost.length() < 2) + return; + // Remove any trailing slash at the end of the update host if (!mUpdateHost.empty() && mUpdateHost.at(mUpdateHost.size() - 1) == '/') mUpdateHost.resize(mUpdateHost.size() - 1); diff --git a/src/gui/login.cpp b/src/gui/login.cpp index bfad5c32..b243fd04 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -91,7 +91,8 @@ LoginDialog::LoginDialog(LoginData *loginData): mPassField->requestFocus(); mLoginButton->setEnabled(canSubmit()); - mRegisterButton->setEnabled(Net::getLoginHandler()->isRegistrationEnabled()); + mRegisterButton->setEnabled(Net::getLoginHandler() + ->isRegistrationEnabled()); } LoginDialog::~LoginDialog() diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index e973fa54..1d01f48c 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -97,15 +97,13 @@ void Minimap::setMap(Map *map) if (map) { std::string tempname = - "graphics/minimaps/"+(*map->getFilename())+".png"; + "graphics/minimaps/" + map->getFilename() + ".png"; ResourceManager *resman = ResourceManager::getInstance(); minimapName = map->getProperty("minimap"); if (minimapName.empty() && resman->exists(tempname)) - { minimapName = tempname; - } mMapImage = resman->getImage(minimapName); } diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 25725a80..ad8ab3c8 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -26,6 +26,7 @@ #include "configuration.h" #include "gui.h" #include "log.h" +#include "main.h" #include "gui/okdialog.h" #include "gui/sdlinput.h" @@ -527,6 +528,15 @@ void ServerDialog::loadServers() std::string type = XML::getProperty(serverNode, "type", "unknown"); server.type = ServerInfo::parseType(type); + + // Ignore unknown server types + if (server.type == ServerInfo::UNKNOWN) + { + logger->log("Ignoring server entry with unknown type: %s", + type.c_str()); + continue; + } + server.name = XML::getProperty(serverNode, "name", std::string()); std::string version = XML::getProperty(serverNode, "minimumVersion", @@ -538,15 +548,11 @@ void ServerDialog::loadServers() // For display in the list if (meetsMinimumVersion) version.clear(); + else if (version.empty()) + version = _("requires a newer version"); else version = strprintf(_("requires v%s"), version.c_str()); - if (server.type == ServerInfo::UNKNOWN) - { - logger->log("Unknown server type: %s", type.c_str()); - continue; - } - for_each_xml_child_node(subNode, serverNode) { if (xmlStrEqual(subNode->name, BAD_CAST "connection")) diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 15cc787a..f7a39240 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -35,6 +35,7 @@ #include "gui/widgets/scrollarea.h" #include "gui/widgets/table.h" +#include "utils/dtor.h" #include "utils/gettext.h" #include <string> @@ -88,7 +89,8 @@ class PlayerTableModel : public TableModel { public: PlayerTableModel() : - mPlayers(NULL) + mPlayers(NULL), + mListModel(new PlayerRelationListModel) { playerRelationsUpdated(); } @@ -96,6 +98,7 @@ public: virtual ~PlayerTableModel() { freeWidgets(); + delete mListModel; if (mPlayers) delete mPlayers; } @@ -139,9 +142,8 @@ public: std::string name = (*player_names)[r]; gcn::Widget *widget = new Label(name); mWidgets.push_back(widget); - gcn::ListModel *playerRelation = new PlayerRelationListModel; - gcn::DropDown *choicebox = new DropDown(playerRelation); + gcn::DropDown *choicebox = new DropDown(mListModel); choicebox->setSelected(player_relations.getRelation(name)); mWidgets.push_back(choicebox); } @@ -170,12 +172,7 @@ public: delete mPlayers; mPlayers = NULL; - for (std::vector<gcn::Widget *>::const_iterator it = mWidgets.begin(); - it != mWidgets.end(); it++) - { - delete *it; - } - + delete_all(mWidgets); mWidgets.clear(); } @@ -187,6 +184,7 @@ public: protected: std::vector<std::string> *mPlayers; std::vector<gcn::Widget *> mWidgets; + PlayerRelationListModel *mListModel; }; /** diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index ebe53261..81ce8107 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -380,6 +380,7 @@ Setup_Video::Setup_Video(): Setup_Video::~Setup_Video() { delete mModeListModel; + delete mModeList; delete mFontSizeListModel; } diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 1a265589..683a6d43 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -185,6 +185,12 @@ public: setCaption(name); } + ~SkillTab() + { + delete mListBox; + mListBox = 0; + } + SkillInfo *getSelectedInfo() { return mListBox->getSelectedInfo(); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 2043da52..25447f30 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -61,7 +61,7 @@ protected: mConfirmDialog(NULL) {} - ~SocialTab() + virtual ~SocialTab() { // Cleanup dialogs if (mInviteDialog) @@ -106,6 +106,14 @@ public: mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); } + ~GuildTab() + { + delete mList; + mList = 0; + delete mScroll; + mScroll = 0; + } + void action(const gcn::ActionEvent &event) { if (event.getId() == "do invite") @@ -179,6 +187,14 @@ public: mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); } + ~PartyTab() + { + delete mList; + mList = 0; + delete mScroll; + mScroll = 0; + } + void action(const gcn::ActionEvent &event) { if (event.getId() == "do invite") @@ -350,6 +366,7 @@ SocialWindow::~SocialWindow() mPartyInviter = ""; } + delete mCreatePopup; } bool SocialWindow::addTab(Guild *guild) diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index ad9c0ed7..c8ebdc98 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -51,6 +51,8 @@ class AttrDisplay : public Container DERIVED, CHANGEABLE, UNKNOWN }; + ~AttrDisplay(); + virtual std::string update(); virtual Type getType() { return UNKNOWN; } @@ -404,6 +406,11 @@ AttrDisplay::AttrDisplay(int id, const std::string &name): mLayout = new LayoutHelper(this); } +AttrDisplay::~AttrDisplay() +{ + delete mLayout; +} + std::string AttrDisplay::update() { int base = player_node->getAttributeBase(mId); diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index 1406a0d0..e46616e0 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -228,6 +228,7 @@ Skin *Theme::readSkin(const std::string &filename) Image *dBorders = Theme::getImageFromTheme(skinSetImage); ImageRect border; + memset(&border, 0, sizeof(ImageRect)); // iterate <widget>'s for_each_xml_child_node(widgetNode, rootNode) diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index 3bf1febe..e2ae5b93 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -26,9 +26,11 @@ #include "resources/image.h" +#include "utils/stringutils.h" + #include <guichan/exception.hpp> -#define CACHE_SIZE 256 +const unsigned int CACHE_SIZE = 256; class TextChunk { @@ -55,8 +57,10 @@ class TextChunk sdlCol.r = color.r; sdlCol.g = color.g; + const char* str = getSafeUtf8String(text); SDL_Surface *surface = TTF_RenderUTF8_Blended( - font, text.c_str(), sdlCol); + font, str, sdlCol); + delete[] str; if (!surface) { @@ -175,7 +179,9 @@ int TrueTypeFont::getWidth(const std::string &text) const } int w, h; - TTF_SizeUTF8(mFont, text.c_str(), &w, &h); + const char* str = getSafeUtf8String(text); + TTF_SizeUTF8(mFont, str, &w, &h); + delete[] str; return w; } diff --git a/src/map.cpp b/src/map.cpp index 7b62746b..33bbccb1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -580,16 +580,13 @@ const std::string Map::getName() const return getProperty("mapname"); } -const std::string *Map::getFilename() const +const std::string Map::getFilename() const { std::string fileName = getProperty("_filename"); int lastSlash = fileName.rfind("/") + 1; int lastDot = fileName.rfind("."); - std::string *sub = new std::string( - fileName.substr(lastSlash, lastDot - lastSlash)); - - return sub; + return fileName.substr(lastSlash, lastDot - lastSlash); } Position Map::checkNodeOffsets(int radius, unsigned char walkMask, @@ -266,7 +266,7 @@ class Map : public Properties /** * Gives the map id based on filepath (ex: 009-1) */ - const std::string *getFilename() const; + const std::string getFilename() const; /** * Check the current position against surrounding blocking tiles, and diff --git a/src/net/download.cpp b/src/net/download.cpp index 2b96a6b9..a2cd4910 100644 --- a/src/net/download.cpp +++ b/src/net/download.cpp @@ -122,7 +122,7 @@ void Download::setWriteFunction(WriteFunction write) bool Download::start() { - logger->log("Starting download: %s\n", mUrl.c_str()); + logger->log("Starting download: %s", mUrl.c_str()); mThread = SDL_CreateThread(downloadThread, this); @@ -140,7 +140,7 @@ bool Download::start() void Download::cancel() { - logger->log("Canceling download: %s\n", mUrl.c_str()); + logger->log("Canceling download: %s", mUrl.c_str()); mOptions.cancel = true; if (mThread && SDL_GetThreadID(mThread) != 0) diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index 721780d2..e2c67f35 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -37,6 +37,7 @@ #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/protocol.h" +#include "net/manaserv/stats.h" #include "resources/colordb.h" @@ -258,15 +259,7 @@ void CharHandler::setCharCreateDialog(CharCreateDialog *window) if (!mCharCreateDialog) return; - std::vector<std::string> attributes; - attributes.push_back(_("Strength:")); - attributes.push_back(_("Agility:")); - attributes.push_back(_("Dexterity:")); - attributes.push_back(_("Vitality:")); - attributes.push_back(_("Intelligence:")); - attributes.push_back(_("Willpower:")); - - mCharCreateDialog->setAttributes(attributes, 60, 1, 20); + mCharCreateDialog->setAttributes(Stats::getLabelVector(), 60, 1, 20); } void CharHandler::requestCharacters() @@ -304,12 +297,10 @@ void CharHandler::newCharacter(const std::string &name, msg.writeInt8(hairstyle); msg.writeInt8(hairColor); msg.writeInt8(gender); - msg.writeInt16(stats[0]); - msg.writeInt16(stats[1]); - msg.writeInt16(stats[2]); - msg.writeInt16(stats[3]); - msg.writeInt16(stats[4]); - msg.writeInt16(stats[5]); + + std::vector<int>::const_iterator it, it_end; + for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) + msg.writeInt16((*it)); accountServerConnection->send(msg); } diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp index 09f68c1e..0d3073f1 100644 --- a/src/net/manaserv/generalhandler.cpp +++ b/src/net/manaserv/generalhandler.cpp @@ -108,9 +108,6 @@ void GeneralHandler::load() registerHandler(mPartyHandler.get()); registerHandler(mPlayerHandler.get()); registerHandler(mTradeHandler.get()); - - Stats::load(); - Stats::informItemDB(); } void GeneralHandler::reload() @@ -194,6 +191,11 @@ void GeneralHandler::stateChanged(State oldState, State newState) GameHandler *game = static_cast<GameHandler*>(Net::getGameHandler()); game->gameLoading(); } + else if (newState == STATE_LOAD_DATA) + { + Stats::load(); + Stats::informItemDB(); + } } } // namespace ManaServ diff --git a/src/net/manaserv/stats.cpp b/src/net/manaserv/stats.cpp index b79b1fd9..f109a232 100644 --- a/src/net/manaserv/stats.cpp +++ b/src/net/manaserv/stats.cpp @@ -198,5 +198,16 @@ namespace Stats { it->second.modifiable, it->second.description); } + + std::vector<std::string> getLabelVector() + { + std::vector<std::string> attributes; + StatMap::const_iterator it, it_end; + for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) + if (it->second.modifiable) + attributes.push_back(it->second.name + ":"); + + return attributes; + } } // namespace Stats } // namespace ManaServ diff --git a/src/net/manaserv/stats.h b/src/net/manaserv/stats.h index c4afbd79..63349095 100644 --- a/src/net/manaserv/stats.h +++ b/src/net/manaserv/stats.h @@ -21,6 +21,9 @@ #ifndef NET_MANASERV_STATS_H #define NET_MANASERV_STATS_H +#include <string> +#include <vector> + namespace ManaServ { namespace Stats { void load(); @@ -30,6 +33,8 @@ namespace Stats { void informItemDB(); void informStatusWindow(); + + std::vector<std::string> getLabelVector(); } // namespace Stats } // namespace ManaServ diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 843e5c9f..8f15691c 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -70,9 +70,6 @@ CharServerHandler::CharServerHandler() void CharServerHandler::handleMessage(Net::MessageIn &msg) { - logger->log("CharServerHandler: Packet ID: %x, Length: %d", - msg.getId(), msg.getLength()); - switch (msg.getId()) { case SMSG_CHAR_LOGIN: @@ -102,16 +99,17 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) switch (msg.readInt8()) { case 0: - errorMessage = _("Access denied."); + errorMessage = _("Access denied. Most likely, there are " + "too many players on this server."); break; case 1: errorMessage = _("Cannot use this ID."); break; default: - errorMessage = _("Unknown failure to select character."); + errorMessage = _("Unknown char-server failure."); break; } - unlockCharSelectDialog(); + Client::setState(STATE_ERROR); break; case SMSG_CHAR_CREATE_SUCCEEDED: diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 7d973ba3..e58acb4d 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -42,6 +42,7 @@ namespace TmwAthena { extern ServerInfo charServer; LoginHandler::LoginHandler(): + mVersionResponse(false), mRegistrationEnabled(true) { static const Uint16 _messages[] = { @@ -187,6 +188,7 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) case SMSG_SERVER_VERSION_RESPONSE: { // TODO: verify these! + msg.readInt8(); // -1 msg.readInt8(); // T msg.readInt8(); // M @@ -194,13 +196,10 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) unsigned int options = msg.readInt32(); - if (options & 1) - { - // Registeration not allowed - mRegistrationEnabled = false; - } + mRegistrationEnabled = (options & 1); - //state = STATE_LOGIN; + // Leave this last + mVersionResponse = true; } break; } @@ -214,7 +213,7 @@ void LoginHandler::connect() bool LoginHandler::isConnected() { - return mNetwork->isConnected(); + return mVersionResponse && mNetwork->isConnected(); } void LoginHandler::disconnect() diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h index 455c75f1..8f6ea321 100644 --- a/src/net/tmwa/loginhandler.h +++ b/src/net/tmwa/loginhandler.h @@ -83,6 +83,7 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler void sendLoginRegister(const std::string &username, const std::string &password); + bool mVersionResponse; bool mRegistrationEnabled; std::string mUpdateHost; Worlds mWorlds; diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp index 77d3fddd..f5d3d01b 100644 --- a/src/playerrelations.cpp +++ b/src/playerrelations.cpp @@ -90,13 +90,20 @@ PlayerRelation::PlayerRelation(Relation relation) PlayerRelationsManager::PlayerRelationsManager() : mPersistIgnores(false), mDefaultPermissions(PlayerRelation::DEFAULT), - mIgnoreStrategy(NULL) + mIgnoreStrategy(0) { } PlayerRelationsManager::~PlayerRelationsManager() { delete_all(mIgnoreStrategies); + + for (std::map<std::string, + PlayerRelation *>::const_iterator it = mRelations.begin(); + it != mRelations.end(); it++) + { + delete it->second; + } } void PlayerRelationsManager::clear() @@ -104,7 +111,9 @@ void PlayerRelationsManager::clear() std::vector<std::string> *names = getPlayers(); for (std::vector<std::string>::const_iterator it = names->begin(); it != names->end(); it++) + { removePlayer(*it); + } delete names; } diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp index 0041cee4..c35a5660 100644 --- a/src/resources/colordb.cpp +++ b/src/resources/colordb.cpp @@ -36,7 +36,7 @@ namespace void ColorDB::load() { if (mLoaded) - return; + unload(); XML::Document *doc = new XML::Document("hair.xml"); xmlNodePtr root = doc->rootNode(); diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp index 117c0bab..fddab500 100644 --- a/src/resources/emotedb.cpp +++ b/src/resources/emotedb.cpp @@ -36,7 +36,7 @@ namespace void EmoteDB::load() { if (mLoaded) - return; + unload(); mLastEmote = 0; diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 57df6143..205268e5 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -109,7 +109,7 @@ static std::string normalized(const std::string &name) void ItemDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing item database..."); diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp index da89302d..0732bb19 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -42,7 +42,7 @@ namespace void MonsterDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing monster database..."); diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp index 03581e13..4f0ee10d 100644 --- a/src/resources/npcdb.cpp +++ b/src/resources/npcdb.cpp @@ -37,7 +37,7 @@ namespace void NPCDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing NPC database..."); diff --git a/src/statuseffect.cpp b/src/statuseffect.cpp index 49619f8a..6ab0b8fa 100644 --- a/src/statuseffect.cpp +++ b/src/statuseffect.cpp @@ -32,6 +32,8 @@ #define STATUS_EFFECTS_FILE "status-effects.xml" +bool StatusEffect::mLoaded = false; + StatusEffect::StatusEffect() : mPersistentParticleEffect(false) {} @@ -113,6 +115,9 @@ StatusEffect *StatusEffect::getStunEffect(int index, bool enabling) void StatusEffect::load() { + if (mLoaded) + unload(); + XML::Document doc(STATUS_EFFECTS_FILE); xmlNodePtr rootNode = doc.rootNode(); @@ -175,8 +180,13 @@ void unloadMap(std::map<int, StatusEffect *> map) void StatusEffect::unload() { + if (!mLoaded) + return; + unloadMap(statusEffects[0]); unloadMap(statusEffects[1]); unloadMap(stunEffects[0]); unloadMap(stunEffects[1]); + + mLoaded = false; } diff --git a/src/statuseffect.h b/src/statuseffect.h index 0fed5748..fc0e7336 100644 --- a/src/statuseffect.h +++ b/src/statuseffect.h @@ -98,6 +98,7 @@ public: static void unload(); private: + static bool mLoaded; std::string mMessage; std::string mSFXEffect; diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 01bf0d3c..9fe3de14 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -21,10 +21,13 @@ #include "utils/stringutils.h" +#include <string.h> #include <algorithm> #include <cstdarg> #include <cstdio> +const int UTF8_MAX_SIZE = 10; + std::string &trim(std::string &str) { std::string::size_type pos = str.find_last_not_of(' '); @@ -164,3 +167,11 @@ const std::string findSameSubstring(const std::string &str1, const std::string & } return str1.substr(0, minLength); } + +const char* getSafeUtf8String(std::string text) +{ + char* buf = new char[text.size() + UTF8_MAX_SIZE]; + memcpy(buf, text.c_str(), text.size()); + memset(buf + text.size(), 0, UTF8_MAX_SIZE); + return buf; +}
\ No newline at end of file diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index 5e4718c0..ec82e240 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -123,4 +123,6 @@ bool isWordSeparator(char chr); const std::string findSameSubstring(const std::string &str1, const std::string &str2); +const char* getSafeUtf8String(std::string text); + #endif // UTILS_STRINGUTILS_H diff --git a/tools/dyecmd/CMakeLists.txt b/tools/dyecmd/CMakeLists.txt new file mode 100644 index 00000000..48566648 --- /dev/null +++ b/tools/dyecmd/CMakeLists.txt @@ -0,0 +1,28 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +PROJECT(MANA_DYECOMMAND) + +IF (NOT VERSION) + SET(VERSION 1.0.0) +ENDIF() + +STRING(REPLACE "." " " _VERSION ${VERSION}) +SEPARATE_ARGUMENTS(_VERSION) +LIST(LENGTH _VERSION _LEN) +IF(NOT (_LEN EQUAL 4 OR _LEN EQUAL 3)) + MESSAGE(FATAL_ERROR "Version needs to be in the form MAJOR.MINOR.RELEASE[.BUILD]") +ENDIF() + +LIST(GET _VERSION 0 VER_MAJOR) +LIST(GET _VERSION 1 VER_MINOR) +LIST(GET _VERSION 2 VER_RELEASE) +IF(_LEN EQUAL 4) + LIST(GET _VERSION 3 VER_BUILD) +ELSE() + SET(VER_BUILD 0) +ENDIF() + +# where to look for cmake modules +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules) + +ADD_SUBDIRECTORY(src) diff --git a/tools/dyecmd/src/CMakeLists.txt b/tools/dyecmd/src/CMakeLists.txt new file mode 100644 index 00000000..f8e717b7 --- /dev/null +++ b/tools/dyecmd/src/CMakeLists.txt @@ -0,0 +1,59 @@ +FIND_PACKAGE(SDL REQUIRED) +FIND_PACKAGE(SDL_image REQUIRED) +FIND_PACKAGE(PNG REQUIRED) + +IF (CMAKE_COMPILER_IS_GNUCXX) + # Help getting compilation warnings + SET(CMAKE_CXX_FLAGS "-Wall") + IF (WIN32) + # This includes enough debug information to get something useful + # from Dr. Mingw while keeping binary size down. Almost useless + # with gdb, though. + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb0 -gstabs2") + ENDIF() +ENDIF() + +SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"") +SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"") +SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${LOCALEDIR}/\\\"") + +IF (CMAKE_BUILD_TYPE) + STRING(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER) + IF((CMAKE_BUILD_TYPE_TOLOWER MATCHES debug) OR + (CMAKE_BUILD_TYPE_TOLOWER MATCHES relwithdebinfo)) + SET(FLAGS "${FLAGS} -DDEBUG") + ENDIF() +ENDIF() + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} + ${SDL_INCLUDE_DIR} + ${SDLIMAGE_INCLUDE_DIR} + ${PNG_INCLUDE_DIR} + ) + +# Fix some stuff that gets not hidden by mainline modules +MARK_AS_ADVANCED(SDLIMAGE_INCLUDE_DIR) +MARK_AS_ADVANCED(SDLIMAGE_LIBRARY) +MARK_AS_ADVANCED(SDLMAIN_LIBRARY) +MARK_AS_ADVANCED(SDL_INCLUDE_DIR) +MARK_AS_ADVANCED(SDL_LIBRARY) + +SET(SRCS + dye.cpp + dye.h + dyecmd.cpp + imagewriter.cpp + imagewriter.h + ) + +SET (PROGRAMS dyecmd) + +ADD_EXECUTABLE(dyecmd WIN32 ${SRCS}) + +TARGET_LINK_LIBRARIES(dyecmd + ${SDL_LIBRARY} + ${SDLIMAGE_LIBRARY} + ${PNG_LIBRARIES}) + +SET_TARGET_PROPERTIES(dyecmd PROPERTIES COMPILE_FLAGS "${FLAGS}") diff --git a/tools/dyecmd/src/dye.cpp b/tools/dyecmd/src/dye.cpp index 76b759cc..77da2ebb 100644..100755 --- a/tools/dyecmd/src/dye.cpp +++ b/tools/dyecmd/src/dye.cpp @@ -21,16 +21,20 @@ #include <algorithm> #include <sstream> +#include <iostream> #include "dye.h" Palette::Palette(const std::string &description) { + mLoaded = false; int size = description.length(); if (size == 0) return; if (description[0] != '#') { - throw; + std::cout << "Missing # in the palette description " + << "in the third parameter." << std::endl; + return; } int pos = 1; @@ -42,25 +46,41 @@ Palette::Palette(const std::string &description) { char c = description[pos + i]; int n; - if ('0' <= c && c <= '9') n = c - '0'; - else if ('A' <= c && c <= 'F') n = c - 'A' + 10; - else if ('a' <= c && c <= 'f') n = c - 'a' + 10; + if ('0' <= c && c <= '9') + n = c - '0'; + else if ('A' <= c && c <= 'F') + n = c - 'A' + 10; + else if ('a' <= c && c <= 'f') + n = c - 'a' + 10; else - throw; + { + std::cout << "invalid Hexadecimal description: " + << description << std::endl; + return; + } v = (v << 4) | n; } Color c = { { v >> 16, v >> 8, v } }; mColors.push_back(c); pos += 6; - if (pos == size) return; - if (description[pos] != ',') break; + if (pos == size) + { + mLoaded = true; + return; + } + if (description[pos] != ',') + break; + ++pos; } + + mLoaded = true; } void Palette::getColor(int intensity, int color[3]) const { + // Return implicit black if (intensity == 0) { color[0] = 0; @@ -107,6 +127,7 @@ void Palette::getColor(int intensity, int color[3]) const Dye::Dye(const std::string &description) { + mLoaded = false; for (int i = 0; i < 7; ++i) mPalettes[i] = 0; @@ -121,7 +142,9 @@ Dye::Dye(const std::string &description) next_pos = length; if (next_pos <= pos + 3 || description[pos + 1] != ':') { - throw; + std::cout << "Dyeing: Missing ':' in channel description." + << std::endl; + return; } int i = 0; switch (description[pos]) @@ -134,12 +157,21 @@ Dye::Dye(const std::string &description) case 'C': i = 5; break; case 'W': i = 6; break; default: - throw; + std::cout << "Dyeing: Invalid channel. Not in [R,G,Y,B,M,C,W]" + << std::endl; + return; } - mPalettes[i] = new Palette(description.substr(pos + 2, next_pos - pos - 2)); + mPalettes[i] = new Palette( + description.substr(pos + 2, next_pos - pos - 2)); + + if (!mPalettes[i]->loaded()) + return; + ++next_pos; } while (next_pos < length); + + mLoaded = true; } Dye::~Dye() @@ -168,47 +200,3 @@ void Dye::update(int color[3]) const if (mPalettes[i - 1]) mPalettes[i - 1]->getColor(cmax, color); } - -void Dye::instantiate(std::string &target, const std::string &palettes) -{ - std::string::size_type next_pos = target.find('|'); - if (next_pos == std::string::npos || palettes.empty()) return; - ++next_pos; - - std::ostringstream s; - s << target.substr(0, next_pos); - std::string::size_type last_pos = target.length(), pal_pos = 0; - do - { - std::string::size_type pos = next_pos; - next_pos = target.find(';', pos); - if (next_pos == std::string::npos) next_pos = last_pos; - if (next_pos == pos + 1 && pal_pos != std::string::npos) - { - std::string::size_type pal_next_pos = palettes.find(';', pal_pos); - s << target[pos] << ':'; - if (pal_next_pos == std::string::npos) - { - s << palettes.substr(pal_pos); - s << target.substr(next_pos); - pal_pos = std::string::npos; - break; - } - s << palettes.substr(pal_pos, pal_next_pos - pal_pos); - pal_pos = pal_next_pos + 1; - } - else if (next_pos > pos + 2) - { - s << target.substr(pos, next_pos - pos); - } - else - { - throw; - } - s << target[next_pos]; - ++next_pos; - } - while (next_pos < last_pos); - - target = s.str(); -} diff --git a/tools/dyecmd/src/dye.h b/tools/dyecmd/src/dye.h index 5a8fe1b5..922f3370 100644..100755 --- a/tools/dyecmd/src/dye.h +++ b/tools/dyecmd/src/dye.h @@ -45,11 +45,19 @@ class Palette */ void getColor(int intensity, int color[3]) const; + /** + * Tells if the palette was successfully loaded. + */ + bool loaded() const + { return mLoaded; } + private: struct Color { unsigned char value[3]; }; std::vector< Color > mColors; + + bool mLoaded; }; /** @@ -73,15 +81,15 @@ class Dye ~Dye(); /** - * Modifies a pixel color. + * Tells if the dye description was successfully loaded. */ - void update(int color[3]) const; + bool loaded() const + { return mLoaded; } /** - * Fills the blank in a dye placeholder with some palette names. + * Modifies a pixel color. */ - static void instantiate(std::string &target, - const std::string &palettes); + void update(int color[3]) const; private: @@ -91,6 +99,7 @@ class Dye * Red, Green, Yellow, Blue, Magenta, White (or rather gray). */ Palette *mPalettes[7]; + bool mLoaded; }; #endif diff --git a/tools/dyecmd/src/dyecmd.cpp b/tools/dyecmd/src/dyecmd.cpp index ebecf9f1..5e06e500 100644..100755 --- a/tools/dyecmd/src/dyecmd.cpp +++ b/tools/dyecmd/src/dyecmd.cpp @@ -23,19 +23,20 @@ #include <SDL/SDL.h> #include <SDL/SDL_image.h> - - #include "dye.h" #include "imagewriter.h" using namespace std; // return values -#define RETURN_OK 1 -#define INVALID_PARAMETER_LIST 100 -#define INVALID_INPUT_IMAGE 101 -#define INVALID_OUTPUT_IMAGE 102 -#define INVALID_DYE_PARAMETER 105 +enum ReturnValues +{ + RETURN_OK = 0, + INVALID_PARAMETER_LIST = 100, + INVALID_INPUT_IMAGE = 101, + INVALID_OUTPUT_IMAGE = 102, + INVALID_DYE_PARAMETER = 105 +}; SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye) { @@ -51,71 +52,104 @@ SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye) rgba.alpha = 255; SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE); - //SDL_FreeSurface(tmpImage); + //SDL_FreeSurface(tmpImage); <-- We'll free the surface later. Uint32 *pixels = static_cast< Uint32 * >(surf->pixels); for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels) { - int alpha = *pixels & 255; + int alpha = (*pixels >> rgba.Ashift) & 255; if (!alpha) continue; int v[3]; - v[0] = (*pixels >> 24) & 255; - v[1] = (*pixels >> 16) & 255; - v[2] = (*pixels >> 8 ) & 255; + + v[0] = (*pixels >> rgba.Rshift) & 255; + v[1] = (*pixels >> rgba.Gshift) & 255; + v[2] = (*pixels >> rgba.Bshift) & 255; dye->update(v); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha; +#else + *pixels = v[0] | (v[1] << 8) | (v[2] << 16) | (alpha << 24); +#endif } return surf; } +void printHelp() +{ + cout << endl + << "This tool is used to dye item graphics used by the Mana client " + << "according to the specification described here: " + << endl << "http://doc.manasource.org/image_dyeing_system" + << endl << endl << + "The tool expects 3 parameters:" << endl + << "dyecmd <source_image> <target_image> <dye_string>" << endl + << "e.g.:" << endl + << "dyecmd \"armor-legs-shorts.png\" " + <<"\"armor-legs-shorts2.png\" \"W:#222255,6666ff\"" << std::endl; +} + int main(int argc, char* argv[]) { Dye* dye = NULL; - SDL_Surface* source = NULL; + SDL_Surface* source = NULL, *target = NULL; + ReturnValues returnValue = RETURN_OK; - // not enough or to many parameters - if (argc != 4) + if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) { - cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST"; - exit(INVALID_PARAMETER_LIST); + printHelp(); } - - try + // not enough or to many parameters + else if (argc != 4) { - dye = new Dye(argv[3]); + cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST"; + printHelp(); + returnValue = INVALID_PARAMETER_LIST; } - catch (exception &e) + else { - cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER"; - exit(INVALID_DYE_PARAMETER); - } + // Start dyeing process. + string inputFile = argv[1]; + string outputFile = argv[2]; + string dyeDescription = argv[3]; - try - { - source = IMG_Load(argv[1]); - if (!source) + dye = new Dye(dyeDescription); + if (!dye->loaded()) { - throw; + cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER"; + printHelp(); + returnValue = INVALID_DYE_PARAMETER; } - } - catch (exception &e) - { - cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE"; - exit(INVALID_INPUT_IMAGE); - } - - SDL_Surface* target = recolor(source, dye); - - if (!ImageWriter::writePNG(target, argv[2])) - { - cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE"; - exit(INVALID_OUTPUT_IMAGE); - } - - SDL_FreeSurface(source); - SDL_FreeSurface(target); - delete dye; - - return 0; + else + { + source = IMG_Load(inputFile.c_str()); + if (!source) + { + cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE"; + printHelp(); + returnValue = INVALID_INPUT_IMAGE; + } + else + { + target = recolor(source, dye); + + if (!ImageWriter::writePNG(target, outputFile)) + { + cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE"; + printHelp(); + returnValue = INVALID_OUTPUT_IMAGE; + } + } // Valid source image file + } // Valid dye parameter + } // Parameters ok + + if (source) + SDL_FreeSurface(source); + if (target) + SDL_FreeSurface(target); + if (dye) + delete dye; + + return returnValue; } diff --git a/tools/dyecmd/src/imagewriter.cpp b/tools/dyecmd/src/imagewriter.cpp index 669b3567..d237abbf 100644..100755 --- a/tools/dyecmd/src/imagewriter.cpp +++ b/tools/dyecmd/src/imagewriter.cpp @@ -22,6 +22,7 @@ #include "imagewriter.h" #include <png.h> +#include <iostream> #include <string> #include <SDL/SDL.h> @@ -32,8 +33,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface, FILE *fp = fopen(filename.c_str(), "wb"); if (!fp) { - // todo - // logger->log("could not open file %s for writing", filename.c_str()); + std::cout << "PNG writer: Could not open file for writing: " + << filename << std::endl; return false; } @@ -49,8 +50,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface, png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (!png_ptr) { - // todo - // logger->log("Had trouble creating png_structp"); + std::cout << "PNG writer: Had trouble creating png_structp" + << std::endl; return false; } @@ -58,16 +59,15 @@ bool ImageWriter::writePNG(SDL_Surface *surface, if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - // todo - // logger->log("Could not create png_info"); + std::cout << "PNG writer: Could not create png_info" << std::endl; return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - // todo - // logger->log("problem writing to %s", filename.c_str()); + std::cout << "PNG writer: problem writing to : " + << filename << std::endl; return false; } @@ -86,8 +86,9 @@ bool ImageWriter::writePNG(SDL_Surface *surface, row_pointers = new png_bytep[surface->h]; if (!row_pointers) { - // todo - // logger->log("Had trouble converting surface to row pointers"); + std::cout + << "PNG writer: Had trouble converting surface to row pointers" + << std::endl; return false; } @@ -105,9 +106,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface, png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - if (SDL_MUSTLOCK(surface)) { + if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); - } return true; } diff --git a/tools/dyecmd/src/imagewriter.h b/tools/dyecmd/src/imagewriter.h index a8bcdf57..a8bcdf57 100644..100755 --- a/tools/dyecmd/src/imagewriter.h +++ b/tools/dyecmd/src/imagewriter.h |