diff --git a/client/AdventureMapButton.cpp b/client/AdventureMapButton.cpp index d9aa8fd0c..abfbe11ce 100644 --- a/client/AdventureMapButton.cpp +++ b/client/AdventureMapButton.cpp @@ -1,18 +1,18 @@ #include "AdventureMapButton.h" #include "CAnimation.h" -#include "CAdvmapInterface.h" +//#include "CAdvmapInterface.h" #include "SDL_Extensions.h" #include "CGameInfo.h" -#include "../lib/CLodHandler.h" -#include "../lib/CGeneralTextHandler.h" -#include "../lib/CTownHandler.h" +//#include "../lib/CGeneralTextHandler.h" +//#include "../lib/CTownHandler.h" #include "../CCallback.h" #include "CConfigHandler.h" -#include "Graphics.h" +//#include "Graphics.h" #include "CBattleInterface.h" #include "CPlayerInterface.h" #include "CMessage.h" #include "CMusicHandler.h" +#include "GUIClasses.h" /* * AdventureMapButton.cpp, part of VCMI engine @@ -26,90 +26,88 @@ CButtonBase::CButtonBase() { + swappedImages = false; bitmapOffset = 0; - curimg=0; - type=-1; - abs=false; - //active=false; - notFreeButton = false; - ourObj=NULL; - state=0; + state=NORMAL; + image = NULL; text = NULL; } CButtonBase::~CButtonBase() { - delete text; - if(notFreeButton) - return; - for (size_t i = 0; isize()-1)); - img = std::max(0, img); - - IImage *toBlit = imgs[curimg]->getImage(img); - - if (abs) + if (text) { - if(toBlit) - { - toBlit->draw(to, pos.x, pos.y); - } + if (state == PRESSED) + text->moveTo(Point(pos.x+pos.w/2+1, pos.y+pos.h/2+1)); else - { - SDL_Rect r = pos; - SDL_FillRect(to, &r, 0x505000); - } - if(text) - {//using "state" instead of "state == 1" screwed up hoverable buttons with text - CSDL_Ext::printAt(text->text, text->x + pos.x + (state == 1), text->y + pos.y + (state == 1), text->font, text->color, to); - } + text->moveTo(Point(pos.x+pos.w/2, pos.y+pos.h/2)); } - else + size_t newPos = (int)state + bitmapOffset; + if (swappedImages) { - toBlit->draw(to, pos.x+ourObj->pos.x,pos.y+ourObj->pos.y); + if (newPos == 0) newPos = 1; + else if (newPos == 1) newPos = 0; } + image->setFrame(newPos); + showAll(screen); + showAll(screen2);//Any way to remove one of showAll()? } -void CButtonBase::showAll( SDL_Surface * to ) +void CButtonBase::addTextOverlay( const std::string &Text, EFonts font, SDL_Color color) { - show(to); + OBJ_CONSTRUCTION_CAPTURING_ALL; + delChild(text); + text = new CLabel(pos.w/2, pos.h/2, font, CENTER, color, Text); + update(); } -void CButtonBase::addTextOverlay( const std::string Text, EFonts font, SDL_Color color) +void CButtonBase::setOffset(int newOffset) { - delete text; - text = new TextOverlay; - text->text = Text; - - const Font *f = graphics->fonts[font]; - text->x = pos.w/2 - f->getWidth(Text.c_str())/2; - text->y = pos.h/2 - f->height/2; - text->font = font; - text->color = color; + if (bitmapOffset == newOffset) + return; + bitmapOffset = newOffset; + update(); } +void CButtonBase::setState(ButtonState newState) +{ + if (state == newState) + return; + state = newState; + update(); +} + +CButtonBase::ButtonState CButtonBase::getState() +{ + return state; +} + +bool CButtonBase::isBlocked() +{ + return state == BLOCKED; +} + +bool CButtonBase::isHighlighted() +{ + return state == HIGHLIGHTED; +} + +void CButtonBase::block(bool on) +{ + setState(on?BLOCKED:NORMAL); +} AdventureMapButton::AdventureMapButton () { - type=2; - abs=true; - hoverable = false; - //active=false; - ourObj=NULL; - state=0; - blocked = actOnDown = false; + hoverable = actOnDown = false; used = LCLICK | RCLICK | HOVER | KEYBOARD; } -//AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ, std::vector * add, bool playerColoredButton) -//{ -// init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ); -//} + AdventureMapButton::AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList &Callback, int x, int y, const std::string &defName,int key, std::vector * add, bool playerColoredButton ) { std::map pom; @@ -117,11 +115,6 @@ AdventureMapButton::AdventureMapButton( const std::string &Name, const std::stri init(Callback, pom, HelpBox, playerColoredButton, defName, add, x, y, key); } -AdventureMapButton::AdventureMapButton( const std::map &Name, const std::string &HelpBox, const CFunctionList &Callback, int x, int y, const std::string &defName, int key, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) -{ - init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, key); -} - AdventureMapButton::AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList &Callback, config::ButtonInfo *info, int key/*=0*/ ) { std::map pom; @@ -129,7 +122,7 @@ AdventureMapButton::AdventureMapButton( const std::string &Name, const std::stri init(Callback, pom, HelpBox, info->playerColoured, info->defName, &info->additionalDefs, info->x, info->y, key); } -AdventureMapButton::AdventureMapButton( const std::pair help, const CFunctionList &Callback, int x, int y, const std::string &defName, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) +AdventureMapButton::AdventureMapButton( const std::pair &help, const CFunctionList &Callback, int x, int y, const std::string &defName, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) { std::map pom; pom[0] = help.first; @@ -137,20 +130,19 @@ AdventureMapButton::AdventureMapButton( const std::pairsoundh->playSound(soundBase::button); - state = 1; + setState(PRESSED); } else if(hoverable && hovered) - state = 3; + setState(HIGHLIGHTED); else - state = 0; + setState(NORMAL); - show(screenBuf); if (actOnDown && down) { callback(); @@ -172,24 +164,18 @@ void AdventureMapButton::hover (bool on) if(hoverable) { if(on) - state = 3; + setState(HIGHLIGHTED); else - state = 0; + setState(NORMAL); } - if(pressedL) - { - if(on) - state = 1; - else - state = hoverable ? 3 : 0; - } + if(pressedL && on) + setState(PRESSED); - ////Hoverable::hover(on); - std::string *name = (vstd::contains(hoverTexts,state)) - ? (&hoverTexts[state]) + std::string *name = (vstd::contains(hoverTexts,getState())) + ? (&hoverTexts[getState()]) : (vstd::contains(hoverTexts,0) ? (&hoverTexts[0]) : NULL); - if(name && name->size() && blocked!=1) //if there is no name, there is nohing to display also + if(name && name->size() && !isBlocked()) //if there is no name, there is nohing to display also { if (LOCPLINT && LOCPLINT->battleInt) //for battle buttons { @@ -216,69 +202,62 @@ void AdventureMapButton::hover (bool on) void AdventureMapButton::init(const CFunctionList &Callback, const std::map &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector * add, int x, int y, int key) { + currentImage = -1; used = LCLICK | RCLICK | HOVER | KEYBOARD; callback = Callback; - blocked = actOnDown = false; - type=2; - abs=true; - hoverable = false; - //active=false; - ourObj=NULL; + actOnDown = hoverable = false; assignedKeys.insert(key); - state=0; hoverTexts = Name; helpBox=HelpBox; - setDef(defName, playerColoredButton); - - if (add && add->size()) - for (size_t i=0; isize();i++) - setDef((*add)[i], playerColoredButton); - if (playerColoredButton) - setPlayerColor(LOCPLINT->playerID); - pos.x += x; pos.y += y; - pos.w = imgs[curimg]->getImage(0)->width(); - pos.h = imgs[curimg]->getImage(0)->height() -1; + + if (!defName.empty()) + imageNames.push_back(defName); + if (add) + for (size_t i=0; isize();i++ ) + imageNames.push_back(add->at(i)); + setIndex(0, playerColoredButton); } -void AdventureMapButton::block( ui8 on ) +void AdventureMapButton::setIndex(size_t index, bool playerColoredButton) { - blocked = on; - state = 0; - bitmapOffset = on ? 2 : 0; - show(screenBuf); + if (index == currentImage || index>=imageNames.size()) + return; + currentImage = index; + setImage(new CAnimation(imageNames[index]), playerColoredButton); } -void AdventureMapButton::setDef(const std::string & defName, bool playerColoredButton, bool reset/*=false*/) +void AdventureMapButton::setImage(CAnimation* anim, bool playerColoredButton) { - if (reset) - { - for (size_t i=0; ideactivate(); + delChild(image); + image = new CAnimImage(anim, getState()); + if (active) + image->activate(); + if (playerColoredButton) + image->playerColored(LOCPLINT->playerID); + + pos.w = image->pos.w; + pos.h = image->pos.h; - imgs.push_back(new CAnimation(defName)); - imgs.back()->load(); } void AdventureMapButton::setPlayerColor(int player) { - for(size_t i =0; isize();j++) - { - imgs[i]->getImage(j)->playerColored(player); - } + if (image) + image->playerColored(player); } void CHighlightableButton::select(bool on) { - selected = on; - state = selected ? 3 : 0; + setState(on?HIGHLIGHTED:NORMAL); - if(selected) + if(on) callback(); else callback2(); @@ -291,32 +270,30 @@ void CHighlightableButton::select(bool on) void CHighlightableButton::clickLeft(tribool down, bool previousState) { - if(blocked) + if(isBlocked()) return; - if (down) + + if (down && !(onlyOn && isHighlighted())) { CCS->soundh->playSound(soundBase::button); - state = 1; - } - else - state = selected ? 3 : 0; + setState(PRESSED); + } - show(screenBuf); - if(previousState && down == false) + if(previousState && down == false && getState() == PRESSED) { - if(!onlyOn || !selected) - select(!selected); + //if(!onlyOn || !isHighlighted()) + select(!isHighlighted()); } } CHighlightableButton::CHighlightableButton( const CFunctionList &onSelect, const CFunctionList &onDeselect, const std::map &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector * add, int x, int y, int key) -: onlyOn(false), selected(false), callback2(onDeselect) +: onlyOn(false), callback2(onDeselect) { init(onSelect,Name,HelpBox,playerColoredButton,defName,add,x,y,key); } -CHighlightableButton::CHighlightableButton( const std::pair help, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) -: onlyOn(false), selected(false) // TODO: callback2(???) +CHighlightableButton::CHighlightableButton( const std::pair &help, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) +: onlyOn(false) // TODO: callback2(???) { ID = myid; std::map pom; @@ -325,7 +302,7 @@ CHighlightableButton::CHighlightableButton( const std::pair &onSelect, int x, int y, const std::string &defName, int myid, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) -: onlyOn(false), selected(false) // TODO: callback2(???) +: onlyOn(false) // TODO: callback2(???) { ID = myid; std::map pom; @@ -335,6 +312,11 @@ CHighlightableButton::CHighlightableButton( const std::string &Name, const std:: void CHighlightableButtonsGroup::addButton(CHighlightableButton* bt) { + if (bt->parent) + bt->parent->removeChild(bt); + addChild(bt); + bt->recActions = defActions;//FIXME: not needed? + bt->callback += boost::bind(&CHighlightableButtonsGroup::selectionChanged,this,bt->ID); bt->onlyOn = true; buttons.push_back(bt); @@ -342,10 +324,11 @@ void CHighlightableButtonsGroup::addButton(CHighlightableButton* bt) void CHighlightableButtonsGroup::addButton(const std::map &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid, const CFunctionList &OnSelect, int key) { + OBJ_CONSTRUCTION_CAPTURING_ALL; CHighlightableButton *bt = new CHighlightableButton(OnSelect, 0, tooltip, HelpBox, false, defName, 0, x, y, key); if(musicLike) { - bt->bitmapOffset = buttons.size() - 3; + bt->setOffset(buttons.size() - 3); } bt->ID = uid; bt->callback += boost::bind(&CHighlightableButtonsGroup::selectionChanged,this,bt->ID); @@ -359,26 +342,7 @@ CHighlightableButtonsGroup::CHighlightableButtonsGroup(const CFunctionList2activate(); - } -} - -void CHighlightableButtonsGroup::deactivate() -{ - for(size_t i=0;ideactivate(); - } + } void CHighlightableButtonsGroup::select(int id, bool mode) @@ -401,23 +365,33 @@ void CHighlightableButtonsGroup::select(int id, bool mode) void CHighlightableButtonsGroup::selectionChanged(int to) { for(size_t i=0;iID!=to && buttons[i]->selected) + if(buttons[i]->ID!=to && buttons[i]->isHighlighted()) buttons[i]->select(false); onChange(to); } void CHighlightableButtonsGroup::show(SDL_Surface * to ) { - for(size_t i=0;iselected)) //if musicLike, print only selected button - buttons[i]->show(to); + for(size_t i=0;iisHighlighted()) + buttons[i]->show(to); } + else + CIntObject::show(to); } void CHighlightableButtonsGroup::showAll( SDL_Surface * to ) { - show(to); + if (musicLike) + { + for(size_t i=0;iisHighlighted()) + buttons[i]->showAll(to); + } + else + CIntObject::showAll(to); } void CHighlightableButtonsGroup::block( ui8 on ) @@ -495,10 +469,11 @@ void CSlider::moveTo(int to) { float part = (float)to/positions; part*=(pos.w-48); - slider->pos.x = part + pos.x + 16; + int newPos = part + pos.x + 16 - slider->pos.x; + slider->moveBy(Point(newPos, 0)); } else - slider->pos.x = pos.x+16; + slider->moveTo(Point(pos.x+16, pos.y)); } else { @@ -506,10 +481,11 @@ void CSlider::moveTo(int to) { float part = (float)to/positions; part*=(pos.h-48); - slider->pos.y = part + pos.y + 16; + int newPos = part + pos.y + 16 - slider->pos.y; + slider->moveBy(Point(0, newPos)); } else - slider->pos.y = pos.y+16; + slider->moveTo(Point(pos.x, pos.y+16)); } if(moved) @@ -518,7 +494,7 @@ void CSlider::moveTo(int to) void CSlider::clickLeft(tribool down, bool previousState) { - if(down && !slider->blocked) + if(down && !slider->isBlocked()) { float pw = 0; float rw = 0; @@ -600,24 +576,25 @@ CSlider::CSlider(int x, int y, int totalw, boost::function Moved, int if(style == 0) { std::string name = horizontal?"IGPCRDIV.DEF":"OVBUTN2.DEF"; + CAnimation *animLeft = new CAnimation(); + animLeft->setCustom(name + ":0", 0); + animLeft->setCustom(name + ":1", 1); + left->setImage(animLeft); + + CAnimation *animRight = new CAnimation(); + animRight->setCustom(name + ":2", 0); + animRight->setCustom(name + ":3", 1); + right->setImage(animRight); - left->imgs.push_back(new CAnimation(name)); - left->imgs.back()->load(); - left->bitmapOffset = 0; - - right->imgs.push_back(new CAnimation(name)); - right->imgs.back()->load(); - right->bitmapOffset = 2; - - slider->imgs.push_back(new CAnimation(name)); - slider->imgs.back()->load(); - slider->bitmapOffset = 4; + CAnimation *animSlider = new CAnimation(); + animSlider->setCustom(name + ":4", 0); + slider->setImage(animSlider); } else { - left->setDef(horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", false); - right->setDef(horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", false); - slider->setDef("SCNRBSL.DEF", false); + left->setImage(new CAnimation(horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF")); + right->setImage(new CAnimation(horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF")); + slider->setImage(new CAnimation("SCNRBSL.DEF")); } slider->actOnDown = true; diff --git a/client/AdventureMapButton.h b/client/AdventureMapButton.h index 7b20e3023..06ce6b72b 100644 --- a/client/AdventureMapButton.h +++ b/client/AdventureMapButton.h @@ -18,6 +18,8 @@ extern SDL_Color tytulowy, tlo, zwykly ; class CAnimation; +class CAnimImage; +class CLabel; namespace config{struct ButtonInfo;} @@ -25,59 +27,63 @@ namespace config{struct ButtonInfo;} class CButtonBase : public KeyShortcut//basic button class { public: - struct TextOverlay + enum ButtonState { - EFonts font; - std::string text; - SDL_Color color; - int x, y; - } *text; - void addTextOverlay(const std::string Text, EFonts font, SDL_Color color = zwykly); + NORMAL=0, + PRESSED=1, + BLOCKED=2, + HIGHLIGHTED=3 + }; +private: + int bitmapOffset; // base offset of visible bitmap from animation + ButtonState state;//current state of button from enum + +public: + bool swappedImages;//fix for some buttons: normal and pressed image are swapped + + void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = zwykly); + void update();//to refresh button after image or text change + + void setOffset(int newOffset); + void setState(ButtonState newState); + ButtonState getState(); + + //just to make code clearer + void block(bool on); + bool isBlocked(); + bool isHighlighted(); + + CAnimImage * image; //image for this button + CLabel * text;//text overlay - int bitmapOffset; //TODO: comment me - int type; //advmapbutton=2 //TODO: comment me - bool abs;//TODO: comment me - //bool active; //if true, this button is active and can be pressed - bool notFreeButton; //TODO: comment me - CIntObject * ourObj; // "owner" - int state; //TODO: comment me - std::vector< CAnimation * > imgs; //images for this button - int curimg; //curently displayed image from imgs - virtual void show(SDL_Surface * to); - virtual void showAll(SDL_Surface * to); - //virtual void activate()=0; - //virtual void deactivate()=0; CButtonBase(); //c-tor virtual ~CButtonBase(); //d-tor }; - class AdventureMapButton : public CButtonBase { + std::vector imageNames;//store list of images that can be used by this button + size_t currentImage; public: - std::map hoverTexts; //state -> text for statusbar + std::map hoverTexts; //text for statusbar std::string helpBox; //for right-click help CFunctionList callback; - bool actOnDown, //runs when mouse is pressed down over it, not when up - hoverable; //if true, button will be highlighted when hovered - ui8 blocked; + bool actOnDown,//runs when mouse is pressed down over it, not when up + hoverable;//if true, button will be highlighted when hovered void clickRight(tribool down, bool previousState); virtual void clickLeft(tribool down, bool previousState); void hover (bool on); - void block(ui8 on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks - //void activate(); // makes button active - //void deactivate(); // makes button inactive (but doesn't delete) AdventureMapButton(); //c-tor - AdventureMapButton( const std::map &, const std::string &HelpBox, const CFunctionList &Callback, int x, int y, const std::string &defName, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList &Callback, int x, int y, const std::string &defName, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor - AdventureMapButton( const std::pair help, const CFunctionList &Callback, int x, int y, const std::string &defName, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor + AdventureMapButton( const std::pair &help, const CFunctionList &Callback, int x, int y, const std::string &defName, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList &Callback, config::ButtonInfo *info, int key=0);//c-tor - //AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ=false, std::vector * add = NULL, bool playerColoredButton = false );//c-tor void init(const CFunctionList &Callback, const std::map &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector * add, int x, int y, int key ); - void setDef(const std::string & defName, bool playerColoredButton, bool reset=false); + + void setIndex(size_t index, bool playerColoredButton=false); + void setImage(CAnimation* anim, bool playerColoredButton=false); void setPlayerColor(int player); }; @@ -86,9 +92,9 @@ class CHighlightableButton { public: CHighlightableButton(const CFunctionList &onSelect, const CFunctionList &onDeselect, const std::map &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector * add, int x, int y, int key=0); - CHighlightableButton(const std::pair help, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor + CHighlightableButton(const std::pair &help, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor CHighlightableButton(const std::string &Name, const std::string &HelpBox, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor - bool onlyOn, selected; + bool onlyOn;//button can not be de-selected int ID; //for identification CFunctionList callback2; //when de-selecting void select(bool on); @@ -107,8 +113,6 @@ public: void addButton(const std::map &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid, const CFunctionList &OnSelect=0, int key=0); //creates new button CHighlightableButtonsGroup(const CFunctionList2 &OnChange, bool musicLikeButtons = false); ~CHighlightableButtonsGroup(); - void activate(); - void deactivate(); void select(int id, bool mode); //mode==0: id is serial; mode==1: id is unique button id void selectionChanged(int to); void show(SDL_Surface * to); diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 01244c485..d217c95c3 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -797,50 +797,52 @@ void CTerrainRect::showPath(const SDL_Rect * extRect, SDL_Surface * to) { if (hvx<0 && hvy<0) { - CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, NULL, to, &genRect(32, 32, x + moveX, y + moveY)); + Rect dstRect = genRect(32, 32, x + moveX, y + moveY); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, NULL, to, &dstRect); } else if(hvx<0) { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap,&genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, x + moveX, y + moveY)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, x + moveX, y + moveY); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } else if (hvy<0) { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap,&genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, x + moveX, y + moveY)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, x + moveX, y + moveY); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } else { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap, &genRect(arrows->ourImages[pn].bitmap->h-hvy,arrows->ourImages[pn].bitmap->w-hvx, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, x + moveX, y + moveY)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, x + moveX, y + moveY); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } } else //standard version { if (hvx<0 && hvy<0) { - CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, NULL, to, &genRect(32, 32, x, y)); + Rect dstRect = genRect(32, 32, x, y); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, NULL, to, &dstRect); } else if(hvx<0) { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap,&genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, x, y)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w, x, y); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } else if (hvy<0) { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap,&genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, x, y)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h, arrows->ourImages[pn].bitmap->w-hvx, x, y); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } else { - CSDL_Ext::blit8bppAlphaTo24bpp - (arrows->ourImages[pn].bitmap, &genRect(arrows->ourImages[pn].bitmap->h-hvy,arrows->ourImages[pn].bitmap->w-hvx, 0, 0), - to, &genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, x, y)); + Rect srcRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, 0, 0); + Rect dstRect = genRect(arrows->ourImages[pn].bitmap->h-hvy, arrows->ourImages[pn].bitmap->w-hvx, x, y); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[pn].bitmap, &srcRect, to, &dstRect); } } SDL_SetClipRect(to, &prevClip); @@ -1219,14 +1221,14 @@ void CAdvMapInt::fswitchLevel() if (position.z) { position.z--; - underground.curimg=0; - underground.show(screenBuf); + underground.setIndex(0,true); + underground.showAll(screenBuf); } else { - underground.curimg=1; + underground.setIndex(1,true); position.z++; - underground.show(screenBuf); + underground.showAll(screenBuf); } updateScreen = true; minimap.draw(screenBuf); @@ -1357,16 +1359,16 @@ void CAdvMapInt::showAll(SDL_Surface *to) if(state != INGAME) return; - kingOverview.show(to); - underground.show(to); - questlog.show(to); - sleepWake.show(to); - moveHero.show(to); - spellbook.show(to); - advOptions.show(to); - sysOptions.show(to); - nextHero.show(to); - endTurn.show(to); + kingOverview.showAll(to); + underground.showAll(to); + questlog.showAll(to); + sleepWake.showAll(to); + moveHero.showAll(to); + spellbook.showAll(to); + advOptions.showAll(to); + sysOptions.showAll(to); + nextHero.showAll(to); + endTurn.showAll(to); minimap.draw(to); heroList.draw(to); @@ -1398,10 +1400,10 @@ void CAdvMapInt::show(SDL_Surface *to) //if advmap needs updating AND (no dialog is shown OR ctrl is pressed) if((animValHitCount % (4/LOCPLINT->sysOpts.mapScrollingSpeed)) == 0 - && + && ( (GH.topInt() == this) || SDL_GetKeyState(NULL)[SDLK_LCTRL] - || SDL_GetKeyState(NULL)[SDLK_RCTRL] + || SDL_GetKeyState(NULL)[SDLK_RCTRL]) ) { if( (scrollingDir & LEFT) && (position.x>-CGI->mh->frameW) ) @@ -1452,7 +1454,7 @@ void CAdvMapInt::centerOn(int3 on) adventureInt->position = on; adventureInt->updateScreen=true; updateMinimap=true; - underground.curimg = on.z; //change underground switch button image + underground.setIndex(on.z,true); //change underground switch button image if(GH.topInt() == this) underground.redraw(); } @@ -2002,7 +2004,7 @@ void CAdvMapInt::tileHovered(const int3 &tile) } } - if(const IShipyard *shipyard = ourInaccessibleShipyard(objAtTile)) + if(ourInaccessibleShipyard(objAtTile)) { CCS->curh->changeGraphic(0, 6); } diff --git a/client/CAnimation.cpp b/client/CAnimation.cpp index f0585c04c..38dbeabc7 100644 --- a/client/CAnimation.cpp +++ b/client/CAnimation.cpp @@ -1,7 +1,7 @@ #include #include -#include "SDL_image.h" +#include #include "../lib/CLodHandler.h" #include "CBitmapHandler.h" @@ -20,6 +20,7 @@ */ extern DLL_EXPORT CLodHandler *spriteh; +extern DLL_EXPORT CLodHandler *bitmaph; typedef std::map > source_map; typedef std::map image_map; @@ -294,9 +295,13 @@ CDefFile::~CDefFile() delete[] palette; } -const std::map > * CDefFile::getEntries() const +const std::map CDefFile::getEntries() const { - return &offset; + std::map ret; + + for (std::map >::const_iterator mapIt = offset.begin(); mapIt!=offset.end(); ++mapIt) + ret[mapIt->first] = mapIt->second.size(); + return ret; } /************************************************************************* @@ -571,16 +576,30 @@ SDLImage::SDLImage(SDL_Surface * from, bool extraRef): SDLImage::SDLImage(std::string filename, bool compressed): margins(0,0) { - int size; - unsigned char * pic = spriteh->giveFile(filename, FILE_GRAPHICS, &size); - surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1); + if (spriteh->haveFile(filename, FILE_GRAPHICS)) + { + int size; + unsigned char * pic=NULL; + pic = spriteh->giveFile(filename, FILE_GRAPHICS, &size); + surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1); + delete [] pic; + } + else if(bitmaph->haveFile(filename, FILE_GRAPHICS)) + surf = BitmapHandler::loadBitmap(filename); + else + { + tlog0<<"Error: file not found: "<w; fullSize.y = surf->h; - delete [] pic; } -void SDLImage::draw(SDL_Surface *where, int posX, int posY, Rect *src) const -{ +void SDLImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, unsigned char rotation) const +{ + if (!surf) + return; Rect sourceRect(margins.x, margins.y, surf->w, surf->h); //TODO: rotation and scaling if (src) @@ -629,8 +648,10 @@ CompImage::CompImage(SDL_Surface * surf) assert(0); } -void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src) const +void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, unsigned char rotation) const { + //rotation & 2 = horizontal rotation + //rotation & 4 = vertical rotation if (!surf) return; Rect sourceRect(sprite); @@ -642,6 +663,11 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src) const //Starting point on SDL surface Point dest(posX+sourceRect.x, posY+sourceRect.y); + if (rotation & 2) + dest.y += sourceRect.h; + if (rotation & 4) + dest.x += sourceRect.w; + sourceRect -= sprite.topLeft(); for (int currY = 0; currY pixels; - blitPos += (dest.y + currY) * where->pitch; + if (rotation & 4) + blitPos += (dest.y - currY) * where->pitch; + else + blitPos += (dest.y + currY) * where->pitch; blitPos += dest.x * bpp; - //Blit block that must be fully visible + //Blit blocks that must be fully visible while (currX + size < sourceRect.w) { - //blit block, pointers will be incremented if needed - BlitBlockWithBpp(bpp, type, size, data, blitPos); + //blit block, pointers will be modified if needed + BlitBlockWithBpp(bpp, type, size, data, blitPos, rotation & 2); currX += size; type = *(data++); @@ -685,30 +714,36 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src) const } //Blit last, semi-visible block size = sourceRect.w - currX; - BlitBlockWithBpp(bpp, type, size, data, blitPos); + BlitBlockWithBpp(bpp, type, size, data, blitPos, rotation & 2); } } -void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const +#define CASEBPP(x,y) case x: BlitBlock(type, size, data, dest); break + +//FIXME: better way to get blitter +void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, bool rotated) const { - switch (bpp) - { - case 2: BlitBlock<2>(type, size, data, dest); - break; - - case 3: BlitBlock<3>(type, size, data, dest); - break; - - case 4: BlitBlock<4>(type, size, data, dest); - break; - default: - assert(0); - break; - } + assert(bpp>1 && bpp<5); + + if (rotated) + switch (bpp) + { + CASEBPP(2,1); + CASEBPP(3,1); + CASEBPP(4,1); + } + else + switch (bpp) + { + CASEBPP(2,1); + CASEBPP(3,1); + CASEBPP(4,1); + } } +#undef CASEBPP //Blit one block from RLE-d surface -template +template void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const { //Raw data @@ -743,15 +778,12 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const case 255: { //Put RGB row - //FIXME: can be optimized - for (int i=0; i::PutColor(dest, palette[type]); + ColorPutter::PutColorRow(dest, palette[type], size); break; } default: { //Put RGBA row - //FIXME: can be optimized for (int i=0; i::PutColorAlpha(dest, palette[type]); break; @@ -848,6 +880,27 @@ void TextParser::parseFile(std::map > &result) } } +IImage * CAnimation::getFromExtraDef(std::string filename) +{ + size_t pos = filename.find(':'); + if (pos == -1) + return NULL; + CAnimation anim(filename.substr(0, pos)); + pos++; + size_t frame = atoi(filename.c_str()+pos); + size_t group = 0; + pos = filename.find(':', pos); + if (pos != -1) + { + group = frame; + frame = atoi(filename.c_str()+pos); + } + anim.load(frame ,group); + IImage * ret = anim.images[group][frame]; + anim.images.clear(); + return ret; +} + bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group) { if (size(group) <= frame) @@ -873,8 +926,10 @@ bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group) } else //load from separate file { - //TODO: compressed images - images[group][frame] = new SDLImage(source[group][frame].c_str()); + IImage * img = getFromExtraDef(source[group][frame].c_str()); + if (!img)//TODO: load compressed image + img = new SDLImage(source[group][frame].c_str()); + images[group][frame] = img; return true; } return false; @@ -902,12 +957,12 @@ void CAnimation::init(CDefFile * file) { TextParser txtFile(name); - if ( txtFile.getType() != 1 ) + if ( file && txtFile.getType() != 1 ) { - const std::map > * defEntries = file->getEntries(); + const std::map defEntries = file->getEntries(); - for (std::map >::const_iterator mapIt = defEntries->begin(); mapIt!=defEntries->end(); ++mapIt) - source[mapIt->first].resize(mapIt->second.size()); + for (std::map::const_iterator mapIt = defEntries.begin(); mapIt!=defEntries.end(); ++mapIt) + source[mapIt->first].resize(mapIt->second); } txtFile.parseFile(source); } @@ -942,27 +997,26 @@ CAnimation::CAnimation(): name(""), compressed(false) { - + init(NULL); } CAnimation::~CAnimation() { - for (group_map::iterator group = images.begin(); group != images.end(); ++group ) - for (image_map::iterator image = group->second.begin(); image != group->second.end(); ++image ) - delete image->second; + if (!images.empty()) + { + tlog2<<"Warning: not all frames were unloaded from "<second.begin(); image != group->second.end(); ++image ) + delete image->second; + } } -void CAnimation::setCustom(IImage * newImage, size_t frame, size_t group) +void CAnimation::setCustom(std::string filename, size_t frame, size_t group) { - assert(newImage); - - IImage * oldImage = getImage(frame,group,false); - if (oldImage); - delete oldImage; - images[group][frame] = newImage; - if (source[group].size() <= frame) source[group].resize(frame+1); + source[group][frame] = filename; + //FIXME: update image if already loaded } IImage * CAnimation::getImage(size_t frame, size_t group, bool verbose) const @@ -1028,20 +1082,6 @@ void CAnimation::unload(size_t frame, size_t group) unloadFrame(frame, group); } -void CAnimation::fixButtonPos() -{ - group_map::iterator groupIter = images.find(0); - if (groupIter != images.end()) - { - image_map::iterator first = groupIter->second.find(0), - second = groupIter->second.find(1); - if (first != second) - { - std::swap (first->second, second->second); - } - } -} - size_t CAnimation::size(size_t group) const { source_map::const_iterator iter = source.find(group); @@ -1050,39 +1090,79 @@ size_t CAnimation::size(size_t group) const return 0; } -CAnimImage::CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group): - anim(name), +CAnimImage::CAnimImage(std::string name, size_t Frame, size_t Group, int x, int y, unsigned char Flags): frame(Frame), - group(Group) + group(Group), + player(-1), + flags(Flags) { - anim.load(frame, group); - pos.w = anim.getImage(frame, group)->width(); - pos.h = anim.getImage(frame, group)->height(); + pos.x += x; + pos.y += y; + anim = new CAnimation(name); + init(); +} + +CAnimImage::CAnimImage(CAnimation *Anim, size_t Frame, size_t Group, int x, int y, unsigned char Flags): + anim(Anim), + frame(Frame), + group(Group), + player(-1), + flags(Flags) +{ + pos.x += x; + pos.y += y; + init(); +} + +void CAnimImage::init() +{ + anim->load(frame, group); + if (flags & CShowableAnim::BASE) + anim->load(0,group); + + IImage *img = anim->getImage(frame, group); + pos.w = img->width(); + pos.h = img->height(); + } CAnimImage::~CAnimImage() { - + anim->unload(frame, group); + if (flags & CShowableAnim::BASE) + anim->unload(0,group); + delete anim; } void CAnimImage::showAll(SDL_Surface *to) { - anim.getImage(frame, group)->draw(to); + anim->getImage(frame, group)->draw(to, pos.x, pos.y); } void CAnimImage::setFrame(size_t Frame, size_t Group) { if (frame == Frame && group==Group) return; - if (anim.size(Group) > Frame) + if (anim->size(Group) > Frame) { - anim.unload(frame, group); - anim.load(Frame, Group); + anim->load(Frame, Group); + anim->unload(frame, group); frame = Frame; group = Group; + if (flags & CShowableAnim::PLAYER_COLORED) + anim->getImage(frame, group)->playerColored(player); } } +void CAnimImage::playerColored(int currPlayer) +{ + player = currPlayer; + flags |= CShowableAnim::PLAYER_COLORED; + anim->getImage(frame, group)->playerColored(player); + if (flags & CShowableAnim::BASE) + anim->getImage(0, group)->playerColored(player); +} + CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags, unsigned int Delay, size_t Group): anim(name, Flags & USE_RLE), group(Group), @@ -1105,7 +1185,7 @@ CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags CShowableAnim::~CShowableAnim() { - + anim.unloadGroup(group); } bool CShowableAnim::set(size_t Group, size_t from, size_t to) diff --git a/client/CAnimation.h b/client/CAnimation.h index b6da0329c..07e681ab1 100644 --- a/client/CAnimation.h +++ b/client/CAnimation.h @@ -58,7 +58,7 @@ public: template void loadFrame(size_t frame, size_t group, ImageLoader &loader) const; - const std::map > * getEntries() const; + const std::map getEntries() const; }; /* @@ -70,7 +70,7 @@ class IImage public: //draws image on surface "where" at position - virtual void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL) const=0; + virtual void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const=0; //decrease ref count, returns true if image can be deleted (refCount <= 0) bool decreaseRef(); @@ -106,7 +106,7 @@ public: SDLImage(SDL_Surface * from, bool extraRef); ~SDLImage(); - void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL) const; + void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const; void playerColored(int player); int width() const; int height() const; @@ -141,9 +141,9 @@ class CompImage : public IImage SDL_Color *palette; //Used internally to blit one block of data - template + template void BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const; - void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const; + void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, bool rotated) const; public: //Load image from def file @@ -152,7 +152,7 @@ public: CompImage(SDL_Surface * surf); ~CompImage(); - void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL) const; + void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const; void playerColored(int player); int width() const; int height() const; @@ -193,6 +193,10 @@ private: //to get rid of copy-pasting error message :] void printError(size_t frame, size_t group, std::string type) const; + //not a very nice method to get image from another def file + //TODO: remove after implementing resource manager + IImage * getFromExtraDef(std::string filename); + public: CAnimation(std::string Name, bool Compressed = false); @@ -200,8 +204,7 @@ public: ~CAnimation(); //add custom surface to the selected position. - //Known issue: IImage should not be used in another CAnimation (results in crash othervice) - void setCustom(IImage * newImage, size_t frame, size_t group=0); + void setCustom(std::string filename, size_t frame, size_t group=0); //get pointer to image from specific group, NULL if not found IImage * getImage(size_t frame, size_t group=0, bool verbose=true) const; @@ -218,9 +221,6 @@ public: void load (size_t frame, size_t group=0); void unload(size_t frame, size_t group=0); - //helper to fix frame order on some buttons - void fixButtonPos(); - //total count of frames in group (including not loaded) size_t size(size_t group=0) const; }; @@ -231,17 +231,26 @@ public: class CAnimImage: public CIntObject { private: - CAnimation anim; + CAnimation* anim; //displayed frame/group size_t frame; size_t group; + int player; + unsigned char flags; + + void init(); public: - CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group=0);//c-tor + CAnimImage(std::string name, size_t Frame, size_t Group=0, int x=0, int y=0, unsigned char Flags=0); + CAnimImage(CAnimation* anim, size_t Frame, size_t Group=0, int x=0, int y=0, unsigned char Flags=0); ~CAnimImage();//d-tor //change displayed frame on this one - void setFrame(size_t Frame, size_t Group=0); + void setFrame(size_t Frame, size_t Group=0); + + //makes image player-colored + void playerColored(int player); + void showAll(SDL_Surface *to); }; @@ -257,6 +266,7 @@ public: HORIZONTAL_FLIP=2, //TODO: will be displayed rotated VERTICAL_FLIP=4, //TODO: will be displayed rotated USE_RLE=8, //RLE-d version, support full alpha-channel for 8-bit images + PLAYER_COLORED=16, //TODO: all loaded images will be player-colored }; protected: CAnimation anim; diff --git a/client/CBattleInterface.cpp b/client/CBattleInterface.cpp index 75b0599da..51048b4b7 100644 --- a/client/CBattleInterface.cpp +++ b/client/CBattleInterface.cpp @@ -1192,7 +1192,6 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe ////blitting menu background and terrain // blitAt(background, pos.x, pos.y); // blitAt(menu, pos.x, 556 + pos.y); -// CSDL_Ext::update(); //preparing buttons and console bOptions = new AdventureMapButton (CGI->generaltexth->zelp[381].first, CGI->generaltexth->zelp[381].second, boost::bind(&CBattleInterface::bOptionsf,this), 3 + pos.x, 561 + pos.y, "icm003.def", SDLK_o); @@ -1208,7 +1207,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe bDefence->assignedKeys.insert(SDLK_SPACE); bConsoleUp = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bConsoleUpf,this), 624 + pos.x, 561 + pos.y, "ComSlide.def", SDLK_UP); bConsoleDown = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bConsoleDownf,this), 624 + pos.x, 580 + pos.y, "ComSlide.def", SDLK_DOWN); - bConsoleDown->bitmapOffset = 2; + bConsoleDown->setOffset(2); console = new CBattleConsole(); console->pos.x = 211 + pos.x; console->pos.y = 560 + pos.y; @@ -1725,13 +1724,13 @@ void CBattleInterface::show(SDL_Surface * to) } //showing buttons - bOptions->show(to); - bSurrender->show(to); - bFlee->show(to); - bAutofight->show(to); - bSpell->show(to); - bWait->show(to); - bDefence->show(to); + bOptions->showAll(to); + bSurrender->showAll(to); + bFlee->showAll(to); + bAutofight->showAll(to); + bSpell->showAll(to); + bWait->showAll(to); + bDefence->showAll(to); //showing window with result of battle if(resWindow) @@ -3941,7 +3940,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect bool weAreAttacker = (owner->curInt->playerID == owner->attackingHeroInstance->tempOwner); if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won { - int text; + int text=-1; switch(br.result) { case 0: text = 304; break; @@ -4020,7 +4019,7 @@ void CBattleResultWindow::show(SDL_Surface *to) CCS->videoh->update(107, 70, background, false, true); SDL_BlitSurface(background, NULL, to, &pos); - exit->show(to); + exit->showAll(to); } void CBattleResultWindow::bExitf() @@ -4061,9 +4060,11 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt animSpeeds->onChange = boost::bind(&CBattleInterface::setAnimSpeed, owner, _1); setToDefault = new AdventureMapButton (CGI->generaltexth->zelp[392].first, CGI->generaltexth->zelp[392].second, boost::bind(&CBattleOptionsWindow::bDefaultf,this), 405, 443, "codefaul.def"); - setToDefault->imgs[0]->fixButtonPos(); + setToDefault->swappedImages = true; + setToDefault->update(); exit = new AdventureMapButton (CGI->generaltexth->zelp[393].first, CGI->generaltexth->zelp[393].second, boost::bind(&CBattleOptionsWindow::bExitf,this), 516, 443, "soretrn.def",SDLK_RETURN); - exit->imgs[0]->fixButtonPos(); + exit->swappedImages = true; + exit->update(); //printing texts to background CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[392], 242, 32, FONT_BIG, tytulowy, background); //window title @@ -4132,12 +4133,12 @@ void CBattleOptionsWindow::show(SDL_Surface *to) SDL_BlitSurface(background, NULL, to, &pos); - setToDefault->show(to); - exit->show(to); - viewGrid->show(to); - movementShadow->show(to); - animSpeeds->show(to); - mouseShadow->show(to); + setToDefault->showAll(to); + exit->showAll(to); + viewGrid->showAll(to); + movementShadow->showAll(to); + animSpeeds->showAll(to); + mouseShadow->showAll(to); } void CBattleOptionsWindow::bDefaultf() diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index da8e07ed9..1cca5b1f7 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -157,9 +157,10 @@ void CBuildingRect::show(SDL_Surface *to) void CBuildingRect::showAll(SDL_Surface *to) { + if (active) + return; CShowableAnim::showAll(to); - - if(LOCPLINT->castleInt->hBuild == this && border && !active) + if(LOCPLINT->castleInt->hBuild == this && border) blitAtLoc(border,0,0,to); } @@ -405,7 +406,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos) amin(townlist->from, LOCPLINT->towns.size() - townlist->SIZE); graphics->blueToPlayersAdv(townInt,LOCPLINT->playerID); - exit->bitmapOffset = 4; + exit->setOffset(4); //growth icons and buildings recreateBuildings(); recreateIcons(); @@ -1483,7 +1484,7 @@ void CHallInterface::showAll(SDL_Surface * to) LOCPLINT->castleInt->statusbar->show(to); printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][bid]->Name(),399+pos.x,12+pos.y,FONT_MEDIUM,zwykly,to); resdatabar->show(to); - exit->show(to); + exit->showAll(to); for(int i=0; i<5; i++) { for(size_t j=0;jshow(to); - cancel->show(to); + buy->showAll(to); + cancel->showAll(to); } } @@ -1648,7 +1649,7 @@ CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mod cancel = new AdventureMapButton ("","",boost::bind(&CBuildWindow::close,this),pos.x+290,pos.y+445,"ICANCEL.DEF",SDLK_ESCAPE); if(state!=7) - buy->state=2; + buy->setState(CButtonBase::BLOCKED); } } @@ -1688,7 +1689,7 @@ void CFortScreen::showAll( SDL_Surface * to) { crePics[i]->showAll(to); } - exit->show(to); + exit->showAll(to); resdatabar->show(to); GH.statusbar->show(to); @@ -1900,6 +1901,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner) spells[i]->pos.x += pos.x; spells[i]->pos.y += pos.y; } + scrolls.unload(); } CMageGuildScreen::~CMageGuildScreen() diff --git a/client/CHeroWindow.cpp b/client/CHeroWindow.cpp index 18d5e7c97..96353a752 100644 --- a/client/CHeroWindow.cpp +++ b/client/CHeroWindow.cpp @@ -88,11 +88,8 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero) questlogButton = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CHeroWindow::questlog,this), 314, 429, "hsbtns4.def", SDLK_q); formations = new CHighlightableButtonsGroup(0); - { - BLOCK_CAPTURING; - formations->addButton(map_list_of(0,CGI->generaltexth->heroscrn[23]),CGI->generaltexth->heroscrn[29], "hsbtns6.def", pos.x+481, pos.y+483, 0, 0, SDLK_t); - formations->addButton(map_list_of(0,CGI->generaltexth->heroscrn[24]),CGI->generaltexth->heroscrn[30], "hsbtns7.def", pos.x+481, pos.y+519, 1, 0, SDLK_l); - } + formations->addButton(map_list_of(0,CGI->generaltexth->heroscrn[23]),CGI->generaltexth->heroscrn[29], "hsbtns6.def", 481, 483, 0, 0, SDLK_t); + formations->addButton(map_list_of(0,CGI->generaltexth->heroscrn[24]),CGI->generaltexth->heroscrn[30], "hsbtns7.def", 481, 519, 1, 0, SDLK_l); tacticsButton = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, 539, 483, SDLK_b); @@ -233,7 +230,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals if(cew->heroInst[g] == hero) noDismiss = true; - if (CKingdomInterface * cki = dynamic_cast(isa)) + if (dynamic_cast(isa)) noDismiss = true; } dismissButton->block(!!hero->visitedTown || noDismiss); diff --git a/client/CKingdomInterface.cpp b/client/CKingdomInterface.cpp index 220d66e07..c20b4a886 100644 --- a/client/CKingdomInterface.cpp +++ b/client/CKingdomInterface.cpp @@ -77,7 +77,7 @@ CKingdomInterface::CKingdomInterface() exit = new AdventureMapButton (CGI->generaltexth->allTexts[600],"", boost::bind(&CKingdomInterface::close,this),748,99+size*116,"OVBUTN1.DEF", SDLK_RETURN); - exit->bitmapOffset = 3; + exit->setOffset(3); statusbar = new CStatusBar(7, 91+size*116,"TSTATBAR.bmp",732); resdatabar = new CResDataBar("KRESBAR.bmp",pos.x+3,pos.y+111+size*116,32,2,76,76); @@ -97,15 +97,15 @@ CKingdomInterface::CKingdomInterface() ObjUp = new AdventureMapButton ("","", boost::bind(&CKingdomInterface::moveObjectList,this,1), 733,24,"OVBUTN4.DEF"); - ObjUp->bitmapOffset = 4; + ObjUp->setOffset(4); ObjDown = new AdventureMapButton ("","", boost::bind(&CKingdomInterface::moveObjectList,this,2), 733,size*116-18,"OVBUTN4.DEF"); - ObjDown->bitmapOffset = 6; + ObjDown->setOffset(6); ObjBottom = new AdventureMapButton ("","", boost::bind(&CKingdomInterface::moveObjectList,this,3), 733,size*116+2,"OVBUTN4.DEF"); - ObjBottom->bitmapOffset = 2; + ObjBottom->setOffset(2); for (size_t i=0; i<8; i++) { diff --git a/client/CMessage.cpp b/client/CMessage.cpp index aa4f6bae0..01bcbaa42 100644 --- a/client/CMessage.cpp +++ b/client/CMessage.cpp @@ -419,7 +419,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) // Compute total width of buttons bw = 20*(ret->buttons.size()-1); // space between all buttons for(size_t i=0; ibuttons.size(); i++) //and add buttons width - bw+=ret->buttons[i]->imgs[0]->getImage(0)->width(); + bw+=ret->buttons[i]->pos.w; winSize.second += 20 + //before button ok->ourImages[0].bitmap->h; //button } @@ -456,13 +456,12 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) { // Position the buttons at the bottom of the window bw = (ret->bitmap->w/2) - (bw/2); - curh = ret->bitmap->h - SIDE_MARGIN - ret->buttons[0]->imgs[0]->getImage(0)->height(); + curh = ret->bitmap->h - SIDE_MARGIN - ret->buttons[0]->pos.h; for(size_t i=0; ibuttons.size(); i++) { - ret->buttons[i]->pos.x = bw + ret->pos.x; - ret->buttons[i]->pos.y = curh + ret->pos.y; - bw += ret->buttons[i]->imgs[0]->getImage(0)->width() + 20; + ret->buttons[i]->moveBy(Point(bw, curh)); + bw += ret->buttons[i]->pos.w + 20; } } for(size_t i=0; icomponents.size(); i++) diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index 2cd56377c..ac2bf8d35 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -1426,12 +1426,10 @@ InfoCard::InfoCard( bool Network ) difficulty = new CHighlightableButtonsGroup(0); { static const char *difButns[] = {"GSPBUT3.DEF", "GSPBUT4.DEF", "GSPBUT5.DEF", "GSPBUT6.DEF", "GSPBUT7.DEF"}; - BLOCK_CAPTURING; for(int i = 0; i < 5; i++) { difficulty->addButton(new CHighlightableButton("", CGI->generaltexth->zelp[24+i].second, 0, 110 + i*32, 450, difButns[i], i)); - difficulty->buttons.back()->pos += pos.topLeft(); } } @@ -2260,7 +2258,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) subTitle = getText(); - int val; + int val=-1; switch(which) { case TOWN: @@ -2698,8 +2696,8 @@ void CBonusSelection::goBack() void CBonusSelection::showAll( SDL_Surface * to ) { - CIntObject::showAll(to); blitAt(background, pos.x, pos.y, to); + CIntObject::showAll(to); show(to); } @@ -2764,7 +2762,7 @@ void CBonusSelection::selectMap( int whichOne ) void CBonusSelection::show( SDL_Surface * to ) { - blitAt(background, pos.x, pos.y, to); + //blitAt(background, pos.x, pos.y, to); //map name std::string mapName = ourHeader->name; @@ -2835,30 +2833,26 @@ void CBonusSelection::updateBonusSelection() const CCampaignScenario &scenario = ourCampaign->camp->scenarios[sInfo.whichMapInCampaign]; const std::vector & bonDescs = scenario.travelOptions.bonusesToChoose; - CDefEssential * twcp = CDefHandler::giveDefEss("TWCRPORT.DEF"); //for yellow border - bonuses->buttons.clear(); { BLOCK_CAPTURING; - static const char *bonDefs[] = {"SPELLBON.DEF", "TWCRPORT.DEF", "GSPBUT5.DEF", "ARTIFBON.DEF", "SPELLBON.DEF", - "PSKILBON.DEF", "SSKILBON.DEF", "BORES.DEF", "GSPBUT5.DEF", "GSPBUT5.DEF"}; + static const char *bonusPics[] = {"SPELLBON.DEF", "TWCRPORT.DEF", "", "ARTIFBON.DEF", "SPELLBON.DEF", + "PSKILBON.DEF", "SSKILBON.DEF", "BORES.DEF", "CREST58.DEF", "HPL000KN"}; for(int i = 0; i < bonDescs.size(); i++) { - CDefEssential * de = CDefHandler::giveDefEss(bonDefs[bonDescs[i].type]); - SDL_Surface * surfToDuplicate = NULL; - bool createNewRef = true; + std::string picName=bonusPics[bonDescs[i].type]; + size_t picNumber=bonDescs[i].info2; std::string desc; switch(bonDescs[i].type) { case 0: //spell - surfToDuplicate = de->ourImages[bonDescs[i].info2].bitmap; desc = CGI->generaltexth->allTexts[715]; boost::algorithm::replace_first(desc, "%s", CGI->spellh->spells[bonDescs[i].info2]->name); break; case 1: //monster - surfToDuplicate = de->ourImages[bonDescs[i].info2 + 2].bitmap; + picNumber = bonDescs[i].info2 + 2; desc = CGI->generaltexth->allTexts[717]; boost::algorithm::replace_first(desc, "%d", boost::lexical_cast(bonDescs[i].info3)); boost::algorithm::replace_first(desc, "%s", CGI->creh->creatures[bonDescs[i].info2]->namePl); @@ -2878,19 +2872,15 @@ void CBonusSelection::updateBonusSelection() } assert(faction != -1); - std::string bldgBitmapName = graphics->ERMUtoPicture[faction][CBuildingHandler::campToERMU(bonDescs[i].info1, faction, std::set())]; - surfToDuplicate = BitmapHandler::loadBitmap(bldgBitmapName); - - createNewRef = false; + picName = graphics->ERMUtoPicture[faction][CBuildingHandler::campToERMU(bonDescs[i].info1, faction, std::set())]; + picNumber = -1; } break; case 3: //artifact - surfToDuplicate = de->ourImages[bonDescs[i].info2].bitmap; desc = CGI->generaltexth->allTexts[715]; boost::algorithm::replace_first(desc, "%s", CGI->arth->artifacts[bonDescs[i].info2]->Name()); break; case 4: //spell scroll - surfToDuplicate = de->ourImages[bonDescs[i].info2].bitmap; desc = CGI->generaltexth->allTexts[716]; boost::algorithm::replace_first(desc, "%s", CGI->spellh->spells[bonDescs[i].info2]->name); break; @@ -2910,7 +2900,7 @@ void CBonusSelection::updateBonusSelection() toPrint.push_back(std::make_pair(g, ptr[g])); } } - surfToDuplicate = de->ourImages[leadingSkill].bitmap; + picNumber = leadingSkill; desc = CGI->generaltexth->allTexts[715]; std::string substitute; //text to be printed instead of %s @@ -2928,7 +2918,6 @@ void CBonusSelection::updateBonusSelection() break; } case 6: //secondary skill - surfToDuplicate = de->ourImages[bonDescs[i].info2].bitmap; desc = CGI->generaltexth->allTexts[718]; boost::algorithm::replace_first(desc, "%s", CGI->generaltexth->levels[bonDescs[i].info3]); //skill level @@ -2950,7 +2939,7 @@ void CBonusSelection::updateBonusSelection() serialResID = 8; break; } - surfToDuplicate = de->ourImages[serialResID].bitmap; + picNumber = serialResID; desc = CGI->generaltexth->allTexts[717]; boost::algorithm::replace_first(desc, "%d", boost::lexical_cast(bonDescs[i].info2)); @@ -2967,7 +2956,7 @@ void CBonusSelection::updateBonusSelection() } break; case 8: //player aka hero crossover - surfToDuplicate = graphics->flags->ourImages[bonDescs[i].info1].bitmap; + picNumber = bonDescs[i].info1; desc = CGI->generaltexth->allTexts[718]; boost::algorithm::replace_first(desc, "%s", CGI->generaltexth->capColors[bonDescs[i].info1]); //player color @@ -2982,40 +2971,37 @@ void CBonusSelection::updateBonusSelection() if (bonDescs[i].info2 == 0xFFFF) { boost::algorithm::replace_first(desc, "%s", CGI->heroh->heroes[0]->name); //hero's name - surfToDuplicate = graphics->portraitLarge[0]; + //surfToDuplicate = graphics->portraitLarge[0]; + //TODO: re-enable - need to get filename or CAnimation with heroes pics } else { boost::algorithm::replace_first(desc, "%s", CGI->heroh->heroes[bonDescs[i].info2]->name); //hero's name - surfToDuplicate = graphics->portraitLarge[bonDescs[i].info2]; + //surfToDuplicate = graphics->portraitLarge[bonDescs[i].info2]; } + picNumber = -1; break; } - bonuses->addButton(new CHighlightableButton(desc, desc, 0, 475 + i*68, 455, bonDefs[bonDescs[i].type], i)); - + bonuses->addButton(new CHighlightableButton(desc, desc, 0, 475 + i*68, 455, "", i)); //create separate surface with yellow border - SDL_Surface * selected = SDL_ConvertSurface(surfToDuplicate, surfToDuplicate->format, surfToDuplicate->flags); - blitAt(twcp->ourImages[1].bitmap, 0, 0, selected); - //replace images on button with new ones - delete bonuses->buttons.back()->imgs[0]; - bonuses->buttons.back()->imgs[0] = new CAnimation(); - bonuses->buttons.back()->imgs[0]->setCustom(new SDLImage(surfToDuplicate, createNewRef), 0); - bonuses->buttons.back()->imgs[0]->setCustom(new SDLImage(selected, false), 1); + if (picNumber != -1) + picName += ":" + boost::lexical_cast(picNumber); + + CAnimation * anim = new CAnimation(); + anim->setCustom(picName, 0); + anim->setCustom("TWCRPORT:1", 1); + bonuses->buttons.back()->setImage(anim); + //FIXME: use show base - //cleaning - delete de; } } if (bonuses->buttons.size() > 0) { bonuses->select(0, 0); } - - delete twcp; - } void CBonusSelection::startMap() diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index eaad77d79..661656303 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -473,9 +473,9 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset, void CGarrisonInt::activate() { for(size_t i = 0; iblocked != !highlighted) + if( (splitButtons[i]->isBlocked()) != !highlighted) splitButtons[i]->block(!highlighted); - + CIntObject::activate(); } @@ -517,13 +517,15 @@ CInfoWindow::CInfoWindow() ID = -1; setDelComps(false); text = NULL; -} +} + void CInfoWindow::close() { GH.popIntTotally(this); if(LOCPLINT) LOCPLINT->showingDialog->setn(false); } + void CInfoWindow::show(SDL_Surface * to) { CIntObject::show(to); @@ -1059,8 +1061,9 @@ void CStatusBar::print(const std::string & text) void CStatusBar::show(SDL_Surface * to) { - SDL_Rect pom = genRect(pos.h,pos.w,pos.x,pos.y); - CSDL_Ext::blitSurface(bg,&genRect(pos.h,pos.w,0,0),to,&pom); + SDL_Rect srcRect = genRect(pos.h,pos.w,0,0); + SDL_Rect dstRect = genRect(pos.h,pos.w,pos.x,pos.y); + CSDL_Ext::blitSurface(bg,&srcRect,to,&dstRect); printAtMiddle(current,middlex,middley,FONT_SMALL,zwykly,to); } @@ -1142,7 +1145,9 @@ void CHeroList::init() { int w = pos.w+1, h = pos.h+4; bg = CSDL_Ext::newSurface(w,h,screen); - CSDL_Ext::blitSurface(adventureInt->bg,&genRect(w,h,pos.x,pos.y),bg,&genRect(w,h,0,0)); + Rect srcRect = genRect(w, h, pos.x, pos.y); + Rect dstRect = genRect(w, h, 0, 0); + CSDL_Ext::blitSurface(adventureInt->bg, &srcRect, bg, &dstRect); } void CHeroList::genList() @@ -1738,7 +1743,8 @@ void CRecruitmentWindow::clickRight(tribool down, bool previousState) for(int i=0;imotion.x,GH.current->motion.y)) + Rect creatureRect = genRect(132, sCREATURE_WIDTH, pos.x+curx, pos.y+64); + if(isItIn(&creatureRect, GH.current->motion.x, GH.current->motion.y)) { CCreInfoWindow *popup = new CCreInfoWindow(creatures[i].ID, 0, 0); GH.pushInt(popup); @@ -1953,9 +1959,9 @@ void CSplitWindow::sliderMoved(int to) void CSplitWindow::show(SDL_Surface * to) { blitAt(bitmap,pos.x,pos.y,to); - ok->show(to); - cancel->show(to); - slider->show(to); + ok->showAll(to); + cancel->showAll(to); + slider->showAll(to); printAtMiddle(boost::lexical_cast(a1) + (!which ? "_" : ""),pos.x+70,pos.y+237,FONT_BIG,zwykly,to); printAtMiddle(boost::lexical_cast(a2) + (which ? "_" : ""),pos.x+233,pos.y+237,FONT_BIG,zwykly,to); animLeft->show(to); @@ -2029,11 +2035,11 @@ void CCreInfoWindow::show(SDL_Surface * to) if(count.size()) printTo(count.c_str(),pos.x+114,pos.y+174,FONT_TIMES,zwykly,to); if(upgrade) - upgrade->show(to); + upgrade->showAll(to); if(dismiss) - dismiss->show(to); + dismiss->showAll(to); if(ok) - ok->show(to); + ok->showAll(to); } CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::function Upg, boost::function Dsm, UpgradeInfo *ui) @@ -2069,7 +2075,7 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi { upgrade = new AdventureMapButton("",CGI->generaltexth->zelp[446].second,boost::function(),76,237,"IVIEWCR.DEF"); upgrade->callback.funcs.clear(); - upgrade->bitmapOffset = 2; + upgrade->setOffset(2); } } @@ -2309,7 +2315,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vectorblocked) + if(ok->isBlocked()) ok->block(false); for(int i=0;iportraitLarge[heroPortrait],170+pos.x,66+pos.y,to); - ok->show(to); + ok->showAll(to); for(int i=0;ishow(to); } @@ -3165,7 +3171,7 @@ void CMarketplaceWindow::makeDeal() if(slider) sliderValue = slider->value; else - sliderValue = !deal->blocked; //should always be 1 + sliderValue = !deal->isBlocked(); //should always be 1 if(!sliderValue) return; @@ -3284,7 +3290,7 @@ std::string CMarketplaceWindow::selectionSubtitle(bool Left) const assert(itemsType[1] == CREATURE || itemsType[1] == RESOURCE); int val = slider ? slider->value * r1 - : ((deal->blocked) ? 0 : r1); + : (((deal->isBlocked())) ? 0 : r1); return boost::lexical_cast(val); } @@ -3295,7 +3301,7 @@ std::string CMarketplaceWindow::selectionSubtitle(bool Left) const case RESOURCE: return boost::lexical_cast( slider->value * r2 ); case ARTIFACT_TYPE: - return (deal->blocked ? "0" : "1"); + return ((deal->isBlocked()) ? "0" : "1"); case PLAYER: return (hRight ? CGI->generaltexth->capColors[hRight->id] : ""); } @@ -3872,19 +3878,22 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface // std::swap(save->imgs[0][0], load->imgs[0][1]); save = new AdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second, boost::bind(&CSystemOptionsWindow::bsavef, this), pos.x+357, pos.y+298, "SOSAVE.DEF", SDLK_s); - save->imgs[0]->fixButtonPos(); + save->swappedImages = true; + save->update(); // restart = new AdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+346, pos.y+357, "SORSTRT", SDLK_r); // std::swap(save->imgs[0][0], restart->imgs[0][1]); mainMenu = new AdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+357, pos.y+357, "SOMAIN.DEF", SDLK_m); - mainMenu->imgs[0]->fixButtonPos(); + mainMenu->swappedImages = true; + mainMenu->update(); quitGame = new AdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second, boost::bind(&CSystemOptionsWindow::bquitf, this), pos.x+246, pos.y+415, "soquit.def", SDLK_q); - quitGame->imgs[0]->fixButtonPos(); - + quitGame->swappedImages = true; + quitGame->update(); backToMap = new AdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second, boost::bind(&CSystemOptionsWindow::breturnf, this), pos.x+357, pos.y+415, "soretrn.def", SDLK_RETURN); - backToMap->imgs[0]->fixButtonPos(); + backToMap->swappedImages = true; + backToMap->update(); backToMap->assignedKeys.insert(SDLK_ESCAPE); heroMoveSpeed = new CHighlightableButtonsGroup(0); @@ -3999,14 +4008,14 @@ void CSystemOptionsWindow::show(SDL_Surface *to) { CSDL_Ext::blitSurface(background, NULL, to, &pos); - save->show(to); - quitGame->show(to); - backToMap->show(to); - mainMenu->show(to); - heroMoveSpeed->show(to); - mapScrollSpeed->show(to); - musicVolume->show(to); - effectsVolume->show(to); + save->showAll(to); + quitGame->showAll(to); + backToMap->showAll(to); + mainMenu->showAll(to); + heroMoveSpeed->showAll(to); + mapScrollSpeed->showAll(to); + musicVolume->showAll(to); + effectsVolume->showAll(to); } CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj) @@ -4101,7 +4110,7 @@ void CTavernWindow::show(SDL_Surface * to) { HeroPortrait *sel = selected ? h2 : h1; - if (selected != oldSelected && !recruit->blocked) + if (selected != oldSelected && !recruit->isBlocked()) { // Selected hero just changed. Update RECRUIT button hover text if recruitment is allowed. oldSelected = selected; @@ -4478,7 +4487,7 @@ void CRClickPopupInt::showAll(SDL_Surface * to) } CArtPlace::CArtPlace(const CArtifactInstance* Art) - : marked(false), ourArt(Art), picked(false), locked(false) + :picked(false), marked(false), locked(false), ourArt(Art) { } @@ -5209,7 +5218,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact if(aoh->curHero == dst.hero) { commonInfo->src.AOH = aoh; - if(ap = aoh->getArtPlace(dst.slot)) + if((ap = aoh->getArtPlace(dst.slot))) break; } } @@ -5383,7 +5392,7 @@ void CExchangeWindow::show(SDL_Surface * to) { blitAt(bg, pos, to); - quit->show(to); + quit->showAll(to); //printing border around window if(screen->w != 800 || screen->h !=600) @@ -5396,7 +5405,7 @@ void CExchangeWindow::show(SDL_Surface * to) for(int g=0; gshow(to); + questlogButton[g]->show(to);//FIXME: for array count(secondary skill) show quest log button? WTF? } garr->show(to); @@ -5648,9 +5657,10 @@ void CShipyardWindow::deactivate() void CShipyardWindow::show( SDL_Surface * to ) { blitAt(bg,pos,to); - CSDL_Ext::blit8bppAlphaTo24bpp(graphics->boatAnims[boat]->ourImages[21 + frame++/8%8].bitmap, NULL, to, &genRect(64, 96, pos.x+110, pos.y+85)); - build->show(to); - quit->show(to); + //FIXME: change to blit by CAnimation + //CSDL_Ext::blit8bppAlphaTo24bpp(graphics->boatAnims[boat]->ourImages[21 + frame++/8%8].bitmap, NULL, to, &genRect(64, 96, pos.x+110, pos.y+85)); + build->showAll(to); + quit->showAll(to); } CShipyardWindow::~CShipyardWindow() @@ -5727,10 +5737,11 @@ CPuzzleWindow::CPuzzleWindow(const int3 &grailPos, float discoveredRatio) //printing necessary things to background int3 moveInt = int3(8, 9, 0); + Rect mapRect = genRect(544, 591, 8, 8); CGI->mh->terrainRect (grailPos - moveInt, adventureInt->anim, &LOCPLINT->cb->getVisibilityMap(), true, adventureInt->heroAnim, - background, &genRect(544, 591, 8, 8), 0, 0, true); + background, &mapRect, 0, 0, true); //printing X sign { @@ -5741,7 +5752,8 @@ CPuzzleWindow::CPuzzleWindow(const int3 &grailPos, float discoveredRatio) } else { - CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[0].bitmap, NULL, background, &genRect(32, 32, x, y)); + Rect dstRect = genRect(32, 32, x, y); + CSDL_Ext::blit8bppAlphaTo24bpp(arrows->ourImages[0].bitmap, NULL, background, &dstRect); } } @@ -5797,7 +5809,7 @@ void CPuzzleWindow::deactivate() void CPuzzleWindow::show(SDL_Surface * to) { blitAt(background, pos.x, pos.y, to); - quitb->show(to); + quitb->showAll(to); resdatabar->draw(to); //blitting disappearing puzzles @@ -6106,14 +6118,20 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn currState.resize(slotsCount+1); costs.resize(slotsCount); totalSumm.resize(RESOURCE_QUANTITY); + std::vector files; + files += "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF"; for (int i=0; iblock(currState[i] == -1); } + files.clear(); + files += "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF"; currState[slotsCount] = getState(slotsCount); - upgradeAll = new AdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, slotsCount), 30, 231, getDefForSlot(slotsCount)); + upgradeAll = new AdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, slotsCount), + 30, 231, "", SDLK_0, &files); quit = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 294, 275, "IOKAY.DEF", SDLK_RETURN); bar = new CGStatusBar(327, 332); @@ -6154,21 +6172,15 @@ void CHillFortWindow::updateGarrisons() } } - if (currState[i] != newState )//we need to update buttons - { - currState[i] = newState; - upgrade[i]->setDef(getDefForSlot(i), false, true); - upgrade[i]->block(currState[i] == -1); - upgrade[i]->hoverTexts[0] = getTextForSlot(i); - } + currState[i] = newState; + upgrade[i]->setIndex(newState); + upgrade[i]->block(currState[i] == -1); + upgrade[i]->hoverTexts[0] = getTextForSlot(i); } int newState = getState(slotsCount); - if (currState[slotsCount] != newState ) - { - currState[slotsCount] = newState; - upgradeAll->setDef(getDefForSlot(slotsCount), false, true); - } + currState[slotsCount] = newState; + upgradeAll->setIndex(newState); garr->recreateSlots(); } @@ -6200,7 +6212,6 @@ void CHillFortWindow::makeDeal(int slot) void CHillFortWindow::showAll (SDL_Surface *to) { CIntObject::showAll(to); - garr->show(to); for ( int i=0; igetCreature(slot) )//we dont have creature here @@ -6312,7 +6301,7 @@ void CThievesGuildWindow::show(SDL_Surface * to) blitAt(background, pos.x, pos.y, to); statusBar->show(to); - exitb->show(to); + exitb->showAll(to); resdatabar->show(to); //showing border around window diff --git a/client/SDL_Extensions.cpp b/client/SDL_Extensions.cpp index 26eaa9648..0b6cacdf9 100644 --- a/client/SDL_Extensions.cpp +++ b/client/SDL_Extensions.cpp @@ -100,6 +100,21 @@ STRONG_INLINE void ColorPutter::PutColor(Uint8 *&ptr, const U } } +template +STRONG_INLINE void ColorPutter::PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count) +{ + Uint32 pixel = ((Uint32)Color.b << 0 ) + ((Uint32)Color.g << 8) + ((Uint32)Color.r << 16); + + for (size_t i=0; i STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColor(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B) { @@ -163,6 +178,22 @@ STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColor(Uint8 *&ptr, const SDL PutColor(ptr, Color.r, Color.g, Color.b); } +template +STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count) +{ + //drop least significant bits of 24 bpp encoded color + Uint16 pixel = (Color.b>>3) + ((Color.g>>2) << 5) + ((Color.r>>3) << 11); + + for (size_t i=0; iflags,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask); @@ -318,7 +349,8 @@ void printAtMiddle(const std::string & text, int x, int y, TTF_Font * font, SDL_ temp = TTF_RenderText_Blended(font,text.c_str(),kolor); break; } - CSDL_Ext::blitSurface(temp,NULL,dst,&genRect(temp->h,temp->w,x-(temp->w/2),y-(temp->h/2))); + SDL_Rect dstRect = genRect(temp->h, temp->w, x-(temp->w/2), y-(temp->h/2)); + CSDL_Ext::blitSurface(temp, NULL, dst, &dstRect); SDL_FreeSurface(temp); } @@ -361,7 +393,8 @@ void printAt(const std::string & text, int x, int y, TTF_Font * font, SDL_Color temp = TTF_RenderText_Blended(font,text.c_str(),kolor); break; } - CSDL_Ext::blitSurface(temp,NULL,dst,&genRect(temp->h,temp->w,x,y)); + SDL_Rect dstRect = genRect(temp->h,temp->w,x,y); + CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect); if(refresh) SDL_UpdateRect(dst,x,y,temp->w,temp->h); SDL_FreeSurface(temp); @@ -463,7 +496,8 @@ void printTo(const std::string & text, int x, int y, TTF_Font * font, SDL_Color temp = TTF_RenderText_Blended(font,text.c_str(),kolor); break; } - CSDL_Ext::blitSurface(temp,NULL,dst,&genRect(temp->h,temp->w,x-temp->w,y-temp->h)); + SDL_Rect dstRect = genRect(temp->h,temp->w,x-temp->w,y-temp->h); + CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect); SDL_UpdateRect(dst,x-temp->w,y-temp->h,temp->w,temp->h); SDL_FreeSurface(temp); } @@ -504,7 +538,8 @@ void printToWR(const std::string & text, int x, int y, TTF_Font * font, SDL_Colo temp = TTF_RenderText_Blended(font,text.c_str(),kolor); break; } - CSDL_Ext::blitSurface(temp,NULL,dst,&genRect(temp->h,temp->w,x-temp->w,y-temp->h)); + SDL_Rect dstRect = genRect(temp->h,temp->w,x-temp->w,y-temp->h); + CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect); SDL_FreeSurface(temp); } @@ -1296,7 +1331,13 @@ void CSDL_Ext::fillRect( SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color ) SDL_Surface * CSDL_Ext::std32bppSurface = NULL; -//instantiation of templates used in CAnimation, required for correct linking -template struct ColorPutter<2,1>; -template struct ColorPutter<3,1>; -template struct ColorPutter<4,1>; \ No newline at end of file +//instantiation of templates used in CAnimation and CCreatureAnimation, required for correct linking +template struct ColorPutter<2,-1>; +template struct ColorPutter<3,-1>; +template struct ColorPutter<4,-1>; +template struct ColorPutter<2, 0>; +template struct ColorPutter<3, 0>; +template struct ColorPutter<4, 0>; +template struct ColorPutter<2, 1>; +template struct ColorPutter<3, 1>; +template struct ColorPutter<4, 1>; \ No newline at end of file diff --git a/client/SDL_Extensions.h b/client/SDL_Extensions.h index 2889706ab..9b092b7f1 100644 --- a/client/SDL_Extensions.h +++ b/client/SDL_Extensions.h @@ -99,6 +99,7 @@ struct ColorPutter static STRONG_INLINE void PutColorAlphaSwitch(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B, const Uint8 & A); static STRONG_INLINE void PutColor(Uint8 *&ptr, const SDL_Color & Color); static STRONG_INLINE void PutColorAlpha(Uint8 *&ptr, const SDL_Color & Color); + static STRONG_INLINE void PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count); }; template @@ -109,6 +110,7 @@ struct ColorPutter<2, incrementPtr> static STRONG_INLINE void PutColorAlphaSwitch(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B, const Uint8 & A); static STRONG_INLINE void PutColor(Uint8 *&ptr, const SDL_Color & Color); static STRONG_INLINE void PutColorAlpha(Uint8 *&ptr, const SDL_Color & Color); + static STRONG_INLINE void PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count); }; typedef void (*BlitterWithRotationVal)(SDL_Surface *src,SDL_Rect srcRect, SDL_Surface * dst, SDL_Rect dstRect, ui8 rotation); diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 189d9f7fc..2a0435e16 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -113,7 +113,7 @@ public: int factionToTurretCreature[F_NUMBER]; //which creature's animation should be used to dispaly creature in turret while siege std::map > stackBonuses; // bonus => name, description - std::vector> expRanks; // stack experience needed for certain rank, index 0 for other tiers (?) + std::vector > expRanks; // stack experience needed for certain rank, index 0 for other tiers (?) std::vector maxExpPerBattle; //%, tiers same as above si8 expAfterUpgrade;//multiplier in % diff --git a/lib/Connection.cpp b/lib/Connection.cpp index b953c9949..7562bb7ac 100644 --- a/lib/Connection.cpp +++ b/lib/Connection.cpp @@ -7,7 +7,6 @@ #ifndef _MSC_VER #include "../lib/RegisterTypes.cpp" -#include "CObjectHandler.h" #endif //for smart objs serialization over net @@ -21,6 +20,7 @@ #include "VCMI_Lib.h" #include "CArtHandler.h" #include "CHeroHandler.h" +#include "CSpellHandler.h" #include "CTownHandler.h" #include "CCampaignHandler.h" #include "NetPacks.h"