From 56cd172b8296626674c2e2b5291a2942fd2ae038 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Mon, 15 Nov 2010 07:15:10 +0000 Subject: [PATCH 1/5] Fixed #296 Partial fix for #314 --- CCallback.cpp | 13 +++++++++---- CCallback.h | 4 ++-- client/CSpellWindow.cpp | 3 ++- hch/CObjectHandler.cpp | 7 ++++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CCallback.cpp b/CCallback.cpp index 64c403a86..69a5d9261 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -120,13 +120,18 @@ int CCallback::getSpellCost(const CSpell * sp, const CGHeroInstance * caster) co return caster->getSpellCost(sp); } -int CCallback::estimateSpellDamage(const CSpell * sp) const +int CCallback::estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const { boost::shared_lock lock(*gs->mx); - if(!gs->curB) - return 0; - + if(!gs->curB) //no battle + { + if (hero) //but we see hero's spellbook + return gs->curB->calculateSpellDmg(sp, hero, NULL, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(2)); + else + return 0; //mage guild + } + //gs->getHero(gs->currentPlayer) const CGHeroInstance * ourHero = gs->curB->heroes[0]->tempOwner == player ? gs->curB->heroes[0] : gs->curB->heroes[1]; return gs->curB->calculateSpellDmg(sp, ourHero, NULL, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(2)); } diff --git a/CCallback.h b/CCallback.h index 91e821c62..4acb47932 100644 --- a/CCallback.h +++ b/CCallback.h @@ -114,7 +114,7 @@ public: virtual const StartInfo * getStartInfo()const =0; virtual const CMapHeader * getMapHeader()const =0; virtual int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const =0; //when called during battle, takes into account creatures' spell cost reduction - virtual int estimateSpellDamage(const CSpell * sp) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg + virtual int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)=0; //get thieves' guild info obtainable while visiting given object virtual int3 getGrailPos(float &outKnownRatio)=0; virtual int getPlayerStatus(int player) const = 0; //-1 if no such player @@ -262,7 +262,7 @@ public: const StartInfo * getStartInfo() const; const CMapHeader * getMapHeader()const ; int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction - int estimateSpellDamage(const CSpell * sp) const; //estimates damage of given spell; returns 0 if spell causes no dmg + int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object int3 getGrailPos(float &outKnownRatio); //returns pos and (via arg) percent of discovered obelisks; TODO: relies on fairness of GUI/AI... :/ diff --git a/client/CSpellWindow.cpp b/client/CSpellWindow.cpp index 388f873b1..2617c0f60 100644 --- a/client/CSpellWindow.cpp +++ b/client/CSpellWindow.cpp @@ -709,7 +709,8 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState) if(down && mySpell != -1) { std::string dmgInfo; - int causedDmg = owner->myInt->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell] ); + const CGHeroInstance * hero = owner->myHero; + int causedDmg = owner->myInt->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell], (hero ? hero : NULL)); if(causedDmg == 0) dmgInfo = ""; else diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index b17a797be..e76d91416 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -6535,9 +6535,10 @@ void CArmedInstance::setArmy(const CCreatureSet &src) } } -CCreatureSet CArmedInstance::getArmy() const -{ - return *this; +CCreatureSet& CArmedInstance::getArmy() const +{ //do not return itself by value, or it will xplode +// CCreatureSet set = *this; return set; + return *((CCreatureSet*)(this)); } void CArmedInstance::randomizeArmy(int type) From f758d13a22df26e292b66a3eae2660746ec7de68 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Mon, 15 Nov 2010 07:16:29 +0000 Subject: [PATCH 2/5] One more file. --- server/CGameHandler.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 904a04f45..72591fa0e 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2153,20 +2153,16 @@ void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreature heroArmy.addToSlot(slot, creatures.slots.begin()->second); creatures.slots.erase (creatures.slots.begin()); } + //move all matching creatures to hero's army + SetGarrisons sg; + sg.garrs[h->id] = heroArmy; + //garrisons need to be synchronized after this, even if object vanishes + sg.garrs[objid] = creatures; + sendAndApply (&sg); - if (creatures.stacksCount() == 0) //all creatures can be moved to hero army - do that + if (creatures.stacksCount()) //show garrison window and let player pick remaining creatures { - SetGarrisons sg; - sg.garrs[h->id] = heroArmy; - sendAndApply(&sg); - } - else //show garrison window and let player pick creatures - { - SetGarrisons sg; - sg.garrs[objid] = creatures; - sendAndApply (&sg); showGarrisonDialog (objid, h->id, true, 0); - return; } } void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we could use ArmedInstance as well From 310a36c8d1e71fc538b2d1e34158ccd534a88b21 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Mon, 15 Nov 2010 12:51:53 +0000 Subject: [PATCH 3/5] Fixed 313 & 314 :) --- client/Client.h | 2 +- client/GUIClasses.cpp | 15 ++++++++++++--- hch/CObjectHandler.cpp | 10 ++++++---- hch/CObjectHandler.h | 2 +- lib/IGameCallback.h | 2 +- server/CGameHandler.cpp | 39 +++++++++++++++++++++++++-------------- server/CGameHandler.h | 2 +- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/client/Client.h b/client/Client.h index 827cf6eed..c1cd88364 100644 --- a/client/Client.h +++ b/client/Client.h @@ -110,7 +110,7 @@ public: void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function &cb){}; void showThievesGuildWindow(int requestingObjId){}; void giveResource(int player, int which, int val){}; - void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) {}; + void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) {}; void takeCreatures (int objid, TSlots creatures){}; void changeCreatureType (int objid, TSlot slot, TCreature creature){}; void showCompInfo(ShowInInfobox * comp){}; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 2f3c8b0bf..bf6d94ace 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -464,8 +464,8 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset, :interx(inx), garOffset(garsOffset), surOffset(SurOffset), highlighted(NULL), sur(pomsur), splitting(false), smallIcons(smallImgs), removableUnits (_removableUnits), twoRows(_twoRows), oup(s1), odown(s2) { - ourUp = s1?s1->tempOwner == LOCPLINT->playerID:false; - ourDown = s2?s2->tempOwner == LOCPLINT->playerID:false; + ourUp = s1?(s1->tempOwner == LOCPLINT->playerID || s1->tempOwner == 254):false; //254 - neutral objects (pandora, banks) + ourDown = s2?(s2->tempOwner == LOCPLINT->playerID || s2->tempOwner == 254):false; set1 = LOCPLINT->cb->getGarrison(s1); set2 = LOCPLINT->cb->getGarrison(s2); pos.x += x; @@ -4418,9 +4418,18 @@ void CGarrisonWindow::show(SDL_Surface * to) quit->show(to); garr->show(to); + std::string title; + if (garr->odown->tempOwner == garr->oup->tempOwner) + title = CGI->generaltexth->allTexts[709]; + else + { + title = CGI->generaltexth->allTexts[35]; + boost::algorithm::replace_first(title, "%s", garr->oup->Slots().begin()->second.type->namePl); + } + blitAt(graphics->flags->ourImages[garr->odown->getOwner()].bitmap,pos.x+28,pos.y+124,to); blitAt(graphics->portraitLarge[static_cast(garr->odown)->portrait],pos.x+29,pos.y+222,to); - printAtMiddle(CGI->generaltexth->allTexts[709],pos.x+275,pos.y+30,FONT_BIG,tytulowy,to); + printAtMiddle(title,pos.x+275,pos.y+30,FONT_BIG,tytulowy,to); } CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ) diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index e76d91416..db2e50441 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -4458,7 +4458,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward { CCreatureSet creatures; creatures.setCreature (0, rID, rVal); - cb->giveCreatures (id, h, creatures); + cb->giveCreatures (id, h, creatures,false); } break; default: @@ -5027,14 +5027,16 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con iw.text.addReplacement (h->name); cb->showInfoDialog(&iw); - cb->giveCreatures (id, h, ourArmy); + cb->giveCreatures (id, h, ourArmy, true); + //boost::bind(&CGPandoraBox::endBattle, this, h, _1) } if(!afterBattle && message.size()) { iw.text << message; cb->showInfoDialog(&iw); } - cb->removeObject(id); + if (!creatures.Slots().size()) + cb->removeObject(id); //only when we don't need to display garrison window } void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const @@ -5905,7 +5907,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons iw.text.addReplacement (loot.buildList()); iw.text.addReplacement (h->name); cb->showInfoDialog(&iw); - cb->giveCreatures (id, h, ourArmy); + cb->giveCreatures (id, h, ourArmy, false); } cb->setObjProperty (id, 15, 0); //bc = NULL } diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index cca770dcd..a0253e4ba 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -223,7 +223,7 @@ public: BattleInfo *battle; //set to the current battle, if engaged void setArmy(const CCreatureSet &src); - CCreatureSet getArmy() const; + CCreatureSet& getArmy() const; void randomizeArmy(int type); ////////////////////////////////////////////////////////////////////////// diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 3d8a7d349..086b54d42 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -86,7 +86,7 @@ public: virtual void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function &cb) =0; //cb will be called when player closes garrison window virtual void showThievesGuildWindow(int requestingObjId) =0; virtual void giveResource(int player, int which, int val)=0; - virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) =0; + virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) =0; virtual void takeCreatures (int objid, TSlots creatures) =0; virtual void changeCreatureType (int objid, TSlot slot, TCreature creature) =0; virtual void showCompInfo(ShowInInfobox * comp)=0; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 72591fa0e..6aa8cee46 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2140,30 +2140,41 @@ void CGameHandler::giveResource(int player, int which, int val) sr.val = gs->players.find(player)->second.resources[which]+val; sendAndApply(&sr); } -void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) +void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) { if (creatures.stacksCount() <= 0) return; CCreatureSet heroArmy = h->getArmy(); - while (creatures.stacksCount()) + std::set takenSlots; + for (TSlots::const_iterator it = creatures.Slots().begin(); it != creatures.Slots().end(); it++) { - int slot = heroArmy.getSlotFor(creatures.Slots().begin()->second.type->idNumber); - if (slot < 0) - break; - heroArmy.addToSlot(slot, creatures.slots.begin()->second); - creatures.slots.erase (creatures.slots.begin()); + int slot = heroArmy.getSlotFor(it->second.type->idNumber); + if (slot >= 0) + { + heroArmy.addToSlot(slot, it->second); //move all matching creatures to hero's army + takenSlots.insert(it->first); //slot id + } } - //move all matching creatures to hero's army + for (std::set::iterator it = takenSlots.begin(); it != takenSlots.end(); it++) + creatures.eraseStack(*it); //delete them from used army + SetGarrisons sg; sg.garrs[h->id] = heroArmy; - //garrisons need to be synchronized after this, even if object vanishes sg.garrs[objid] = creatures; sendAndApply (&sg); - if (creatures.stacksCount()) //show garrison window and let player pick remaining creatures + if (remove) //show garrison window and let player pick remaining creatures { - showGarrisonDialog (objid, h->id, true, 0); + if (creatures.stacksCount()) //Pandora needs to exist until we close garrison window + { + showGarrisonDialog (objid, h->id, true, boost::bind(&CGameHandler::removeObject, this, objid)); + } + else + removeObject(objid); } + else if (creatures.stacksCount()) + showGarrisonDialog (objid, h->id, true, 0); + } void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we could use ArmedInstance as well { @@ -2658,8 +2669,8 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, if(what==1) //swap { - if ( (s1->tempOwner != player && S1.slots[p1].count) - || (s2->tempOwner != player && S2.slots[p2].count)) + if ( ((s1->tempOwner != player && s1->tempOwner != 254) && S1.slots[p1].count) //why 254?? + || ((s2->tempOwner != player && s2->tempOwner != 254) && S2.slots[p2].count)) { complain("Can't take troops from another player!"); return false; @@ -2676,7 +2687,7 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, else if(what==2)//merge { if (( S1.slots[p1].type != S2.slots[p2].type && complain("Cannot merge different creatures stacks!")) - || (s1->tempOwner != player && S2.slots[p2].count) && complain("Can't take troops from another player!")) + || ((s1->tempOwner != player && s1->tempOwner != 254) && S2.slots[p2].count) && complain("Can't take troops from another player!")) return false; S2.slots[p2].count += S1.slots[p1].count; diff --git a/server/CGameHandler.h b/server/CGameHandler.h index b68d8991a..771e82ca6 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -135,7 +135,7 @@ public: void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function &cb); void showThievesGuildWindow(int requestingObjId); //TODO: make something more general? void giveResource(int player, int which, int val); - void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures); + void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove); void takeCreatures (int objid, TSlots creatures); void changeCreatureType (int objid, TSlot slot, TCreature creature); void showCompInfo(ShowInInfobox * comp); From 265d7a22d64c7dc350f6dda316acfaf07107b36b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 15 Nov 2010 15:15:00 +0000 Subject: [PATCH 4/5] Animation system update: -- files moved to /client, GUI classes added -- handling of creatures, used in creature cards, fixed #469 \ #490 -- handling of town buildings #631 crash at hill fort fixed --- client/AdventureMapButton.cpp | 2 +- {hch => client}/CAnimation.cpp | 327 ++++++++++++++++++++++++++++++--- {hch => client}/CAnimation.h | 136 +++++++++++++- client/CBattleInterface.cpp | 8 +- client/CCastleInterface.cpp | 305 +++++++++++------------------- client/CCastleInterface.h | 27 ++- client/CMessage.cpp | 2 +- client/CPreGame.cpp | 12 +- client/GUIClasses.cpp | 105 +++++------ client/GUIClasses.h | 31 ++-- client/Makefile.am | 4 +- client/Makefile.in | 38 ++-- hch/CLodHandler.cpp | 14 +- 13 files changed, 658 insertions(+), 353 deletions(-) rename {hch => client}/CAnimation.cpp (64%) rename {hch => client}/CAnimation.h (51%) diff --git a/client/AdventureMapButton.cpp b/client/AdventureMapButton.cpp index fee69602c..17aacccd8 100644 --- a/client/AdventureMapButton.cpp +++ b/client/AdventureMapButton.cpp @@ -1,5 +1,5 @@ #include "AdventureMapButton.h" -#include "../hch/CAnimation.h" +#include "CAnimation.h" #include "CAdvmapInterface.h" #include "SDL_Extensions.h" #include "CGameInfo.h" diff --git a/hch/CAnimation.cpp b/client/CAnimation.cpp similarity index 64% rename from hch/CAnimation.cpp rename to client/CAnimation.cpp index ed5294d8c..ebfb98bd8 100644 --- a/hch/CAnimation.cpp +++ b/client/CAnimation.cpp @@ -1,13 +1,15 @@ #include #include #include +#include #include "SDL.h" #include "SDL_image.h" -#include "../client/CBitmapHandler.h" +#include "CBitmapHandler.h" #include "CAnimation.h" -#include "CLodHandler.h" +#include "SDL_Extensions.h" +#include "../hch/CLodHandler.h" /* * CAnimation.cpp, part of VCMI engine @@ -19,7 +21,6 @@ * */ - extern DLL_EXPORT CLodHandler *spriteh; /************************************************************************* @@ -267,8 +268,9 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette break; } - SDL_Color ttcol = ret->format->palette->colors[0]; - Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused); + SDL_Color *col = ret->format->palette->colors; + + Uint32 keycol = SDL_MapRGBA(ret->format, col[0].r, col[0].b, col[0].g, col[0].unused); SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol); return ret; }; @@ -282,6 +284,15 @@ BMPPalette * CDefFile::getPalette() CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL) { + static SDL_Color H3Palette[8] = {{ 0, 0, 0, 255}, + { 0, 0, 0, 192}, + { 0, 0, 0, 128}, + { 0, 0, 0, 64}, + { 0, 0, 0, 32}, + {255, 255, 0, 255}, + {255, 255, 0, 255}, + {255, 255, 0, 255}};//H3 palette for shadow\selection highlight + data = spriteh->giveFile(Name, FILE_ANIMATION, &datasize); if (!data) { @@ -292,37 +303,41 @@ CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL) colors = new BMPPalette[256]; int it = 0; - //int type = readNormalNr(data, it); it+=4; + type = readNormalNr(data, it); it+=4; //int width = readNormalNr(data, it); it+=4;//not used //int height = readNormalNr(data, it); it+=4; - it+=12; + it+=8; unsigned int totalBlocks = readNormalNr(data, it); it+=4; - for (unsigned int i=0; i<256; i++) + for (unsigned int i= 0; i<256; i++) { colors[i].R = data[it++]; colors[i].G = data[it++]; colors[i].B = data[it++]; colors[i].F = 0; } + memcpy(colors, H3Palette, (type == 66)? 32:20);//initialize shadow\selection colors - offset.resize(totalBlocks); offList.insert(datasize); for (unsigned int i=0; i 21) + break;//FIXME: crude workaround: if some groups are not present + //(common for creatures) parser will exit before reaching them } } } @@ -532,7 +558,6 @@ CAnimation::CAnimation(std::string Name, bool Compressed): int dotPos = name.find_last_of('.'); if ( dotPos != -1 ) name.erase(dotPos); - CDefFile * file = getFile(); init(file); delete file; @@ -548,12 +573,11 @@ CAnimation::CAnimation(): CAnimation::~CAnimation() { - delete defPalette; - + delete [] defPalette; for (size_t i = 0; i < entries.size(); i++) for (size_t j = 0; j < entries.at(i).size(); j++) { - delete entries[i][j].data; + delete [] entries[i][j].data; if (entries[i][j].surf) SDL_FreeSurface(entries[i][j].surf); } @@ -575,21 +599,25 @@ void CAnimation::add(SDL_Surface * surf, bool shared, size_t group) entries[group].back().surf = surf; } -void CAnimation::purgeCompressed() +void CAnimation::removeDecompressed(size_t frame, size_t group) { - for (size_t group; group < entries.size(); group++) - for (size_t frame; frame < entries[group].size(); frame++) - if (entries[group][frame].surf) - SDL_FreeSurface(entries[group][frame].surf); + AnimEntry &e = entries[group][frame]; + if (e.surf && e.data) + { + SDL_FreeSurface(e.surf); + e.surf = NULL; + } } SDL_Surface * CAnimation::image(size_t frame) { size_t group=0; - for (; group entries[group].size(); group++) + while (group entries[group].size()) frame -= entries[group].size(); - return image(frame, group); + if (group w; + pos.h = anim.image(frame, group)->h; +} + +CAnimImage::~CAnimImage() +{ + +} + +void CAnimImage::show(SDL_Surface *to) +{ + blitAtLoc(anim.image(frame, group), 0,0, to); +} + +void CAnimImage::setFrame(size_t Frame, size_t Group) +{ + if (frame == Frame && group==Group) + return; + if (anim.groupSize(Group) > Frame) + { + anim.unload(frame, group); + anim.load(Frame, Group); + frame = Frame; + group = Group; + } +} +*/ +CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags, unsigned int Delay, size_t Group): + anim(name, Flags), + group(Group), + frame(0), + first(0), + flags(Flags), + frameDelay(Delay), + value(0), + xOffset(0), + yOffset(0) +{ + pos.x+=x; + pos.y+=y; + + anim.loadGroup(group); + last = anim.groupSize(group); + pos.w = anim.image(0, group)->w; + pos.h = anim.image(0, group)->h; +} + +CShowableAnim::~CShowableAnim() +{ + +} + +bool CShowableAnim::set(size_t Group, size_t from, size_t to) +{ + size_t max = anim.groupSize(Group); + + if (max>to) + max = to; + + if (max < from || max == 0) + return false; + + anim.load(Group); + anim.unload(group); + group = Group; + frame = first = from; + last = max; + value = 0; + return true; +} + +bool CShowableAnim::set(size_t Group) +{ + if (anim.groupSize(Group)== 0) + return false; + if (group != Group) + { + anim.loadGroup(Group); + anim.unloadGroup(group); + first = 0; + group = Group; + last = anim.groupSize(Group); + } + frame = value = 0; + return true; +} + +void CShowableAnim::reset() +{ + value = 0; + frame = first; + if (callback) + callback(); +} + +void CShowableAnim::movePic( int byX, int byY) +{ + xOffset += byX; + yOffset += byY; +} + +void CShowableAnim::show(SDL_Surface *to) +{ + if ( flags & FLAG_BASE && frame != first) + blitImage(anim.image(first, group), to); + blitImage(anim.image(frame, group), to); + + if ( ++value == frameDelay ) + { + value = 0; + if (flags & FLAG_COMPRESSED) + anim.removeDecompressed(frame, group); + if ( ++frame == last) + reset(); + } + +} + +void CShowableAnim::showAll(SDL_Surface *to) +{ + show(to); +} + +void CShowableAnim::blitImage(SDL_Surface *what, SDL_Surface *to) +{ + assert(what); + //TODO: SDL RLE? + SDL_Rect dstRect=genRect(pos.h, pos.w, pos.x, pos.y); + SDL_Rect srcRect; + + srcRect.x = xOffset; + srcRect.y = yOffset; + srcRect.w = pos.w; + srcRect.h = pos.h; + + /*if ( flags & FLAG_ROTATED ) + {} //TODO: rotate surface + else */ + if (flags & FLAG_ALPHA && what->format->BytesPerPixel == 1) //alpha on 8-bit surf - use custom blitter + CSDL_Ext::blit8bppAlphaTo24bpp(what, &srcRect, to, &dstRect); + else + CSDL_Ext::blitSurface(what, &srcRect, to, &dstRect); +} + +void CShowableAnim::rotate(bool on) +{ + if (on) + flags |= FLAG_ROTATED; + else + flags &= ~FLAG_ROTATED; +} + +CCreatureAnim::CCreatureAnim(int x, int y, std::string name, unsigned char flags, EAnimType type): + CShowableAnim(x,y,name,flags,3,type) +{ + if (flags & FLAG_PREVIEW) + callback = boost::bind(&CCreatureAnim::loopPreview,this); +}; + +void CCreatureAnim::loopPreview() +{ + std::vector available; + if (anim.groupSize(ANIM_HOLDING)) + available.push_back(ANIM_HOLDING); + + if (anim.groupSize(ANIM_HITTED)) + available.push_back(ANIM_HITTED); + + if (anim.groupSize(ANIM_DEFENCE)) + available.push_back(ANIM_DEFENCE); + + if (anim.groupSize(ANIM_ATTACK_FRONT)) + available.push_back(ANIM_ATTACK_FRONT); + + if (anim.groupSize(ANIM_CAST_FRONT)) + available.push_back(ANIM_CAST_FRONT); + + size_t rnd = rand()%(available.size()*2); + + if (rnd >= available.size()) + { + if ( anim.groupSize(ANIM_MOVING) == 0 )//no moving animation present + addLast( ANIM_HOLDING ); + else + addLast( ANIM_MOVING ) ; + } + else + addLast(available[rnd]); +} + +void CCreatureAnim::addLast(EAnimType newType) +{ + if (type != ANIM_MOVING && newType == ANIM_MOVING)//starting moving - play init sequence + { + queue.push( ANIM_MOVE_START ); + } + else if (type == ANIM_MOVING && newType != ANIM_MOVING )//previous anim was moving - finish it + { + queue.push( ANIM_MOVE_END); + } + if (newType == ANIM_TURN_L || newType == ANIM_TURN_R) + queue.push(newType); + + queue.push(newType); +} + +void CCreatureAnim::reset() +{ + //if we are in the middle of rotation - set flag + if (type == ANIM_TURN_L && !queue.empty() && queue.front() == ANIM_TURN_L) + flags |= FLAG_ROTATED; + if (type == ANIM_TURN_R && !queue.empty() && queue.front() == ANIM_TURN_R) + flags &= ~FLAG_ROTATED; + + while (!queue.empty())//FIXME: remove dublication + { + EAnimType at = queue.front(); + queue.pop(); + if (set(at)) + return; + } + if (callback) + callback(); + while (!queue.empty()) + { + EAnimType at = queue.front(); + queue.pop(); + if (set(at)) + return; + } + tlog0<<"Warning: next sequence is not found for animation!\n"; +} + +void CCreatureAnim::clearAndSet(EAnimType type) +{ + while (!queue.empty()) + queue.pop(); + set(type); +} diff --git a/hch/CAnimation.h b/client/CAnimation.h similarity index 51% rename from hch/CAnimation.h rename to client/CAnimation.h index c74ad6104..eb8f0b94e 100644 --- a/hch/CAnimation.h +++ b/client/CAnimation.h @@ -1,10 +1,15 @@ #ifndef __CANIMATION_H__ #define __CANIMATION_H__ +#include + #include #include +#include #include + #include "../global.h" +#include "GUIBase.h" /* * CAnimation.h, part of VCMI engine @@ -37,6 +42,7 @@ private: ui32 TopMargin; }; + unsigned int type; unsigned char * data; int datasize; BMPPalette * colors; @@ -138,7 +144,7 @@ public: void add(SDL_Surface * surf, bool shared=false, size_t group=0); //removes all surfaces which have compressed data - void purgeCompressed(); + void removeDecompressed(size_t frame, size_t group); //get pointer to surface, this function ignores groups (like ourImages in DefHandler) SDL_Surface * image (size_t frame); @@ -173,7 +179,135 @@ public: //total count of frames in whole anim size_t size() const; +}; +/* +//Class for displaying one image from animation +class CAnimImage: public CIntObject +{ +private: + CAnimation anim; + size_t frame;//displayed frame/group + size_t group; +public: + CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group=0);//c-tor + ~CAnimImage();//d-tor + + //change displayed frame on this one + void setFrame(size_t Frame, size_t Group=0); + void show(SDL_Surface *to); + //TODO: showAll(); +}; +*/ +//Base class for displaying animation, used as superclass for different animations +class CShowableAnim: public CIntObject +{ +public: + enum EFlags + { + FLAG_BASE=1, //base frame will be blitted before current one + FLAG_COMPRESSED=2, //animations will be loaded in compressed state + FLAG_ROTATED=4, //will be displayed rotated + FLAG_ALPHA=8, //if image is 8bbp it will be printed with transparency (0=opaque, 255=transparent) + FLAG_USERLE=16, //not used for now, enable RLE compression from SDL + FLAG_PREVIEW=32 //for creatures only: several animation (move, attack, defence...) will be randomly selected + }; + +protected: + CAnimation anim; + size_t group, frame;//current frame + + size_t first, last; //animation range + + unsigned char flags;//flags from EFlags enum + + unsigned int frameDelay;//delay in frames of each image + + unsigned int value;//how many times current frame was showed + + //blit image with optional rotation, fitting into rect, etc + void blitImage(SDL_Surface *what, SDL_Surface *to); + + //For clipping in rect, offsets of picture coordinates + int xOffset, yOffset; + +public: + //called when next animation sequence is required + boost::function callback; + + CShowableAnim(int x, int y, std::string name, unsigned char flags, unsigned int Delay=4, size_t Group=0); + ~CShowableAnim(); + + //set animation to group or part of group + bool set(size_t Group); + bool set(size_t Group, size_t from, size_t to=-1); + + //set rotation flag + void rotate(bool on); + + //move displayed part of picture (if picture is clipped to rect) + void movePic( int byX, int byY); + + //set frame to first, call callback + virtual void reset(); + + //show current frame and increase counter + void show(SDL_Surface *to); + void showAll(SDL_Surface *to); +}; + +class CCreatureAnim: public CShowableAnim +{ +public: + + enum EAnimType // list of creature animations, numbers were taken from def files + { + ANIM_MOVING=0, //will automatically add MOVE_START and MOVE_END to queue + ANIM_MOUSEON=1, + ANIM_HOLDING=2, + ANIM_HITTED=3, + ANIM_DEFENCE=4, + ANIM_DEATH=5, + //ANIM_DEATH2=6, //unused? + ANIM_TURN_L=7, //will automatically play second part of anim and rotate creature + ANIM_TURN_R=8, //same + //ANIM_TURN_L2=9, //identical to previous? + //ANIM_TURN_R2=10, + ANIM_ATTACK_UP=11, + ANIM_ATTACK_FRONT=12, + ANIM_ATTACK_DOWN=13, + ANIM_SHOOT_UP=14, + ANIM_SHOOT_FRONT=15, + ANIM_SHOOT_DOWN=16, + ANIM_CAST_UP=17, + ANIM_CAST_FRONT=18, + ANIM_CAST_DOWN=19, + ANIM_2HEX_ATTACK_UP=17, + ANIM_2HEX_ATTACK_FRONT=18, + ANIM_2HEX_ATTACK_DOWN=19, + ANIM_MOVE_START=20, //no need to use this two directly - ANIM_MOVING will be enought + ANIM_MOVE_END=21 + }; + +private: + // queue of animations waiting to be displayed + std::queue queue; + + //this funcction is used as callback if preview flag was set during construction + void loopPreview(); + +public: + //change anim to next if queue is not empty, call callback othervice + void reset(); + + //add sequence to the end of queue + void addLast(EAnimType newType); + + //clear queue and set animation to this sequence + void clearAndSet(EAnimType type); + + CCreatureAnim(int x, int y, std::string name, unsigned char flags=FLAG_COMPRESSED | FLAG_ALPHA | FLAG_PREVIEW, + EAnimType type=ANIM_HOLDING); }; diff --git a/client/CBattleInterface.cpp b/client/CBattleInterface.cpp index f9416797f..1b1704554 100644 --- a/client/CBattleInterface.cpp +++ b/client/CBattleInterface.cpp @@ -4,7 +4,7 @@ #include "SDL_Extensions.h" #include "CAdvmapInterface.h" #include "AdventureMapButton.h" -#include "../hch/CAnimation.h" +#include "CAnimation.h" #include "../hch/CObjectHandler.h" #include "../hch/CHeroHandler.h" #include "../hch/CDefHandler.h" @@ -563,8 +563,8 @@ void CDefenceAnim::endAnim() if(IDby!=-1) owner->printConsoleAttacked(stackID, dmg, amountKilled, IDby); - const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false); - const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false); + //const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false); + //const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false); CBattleAnimation::endAnim(); @@ -600,7 +600,7 @@ bool CBattleStackMoved::init() endAnim(); return false; } - bool twoTiles = movedStack->doubleWide(); + //bool twoTiles = movedStack->doubleWide(); Point begPosition = CBattleHex::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner); Point endPosition = CBattleHex::getXYUnitAnim(destHex, movedStack->attackerOwned, movedStack, owner); diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index 597c53035..5fc28c0f6 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -2,6 +2,7 @@ #include "CCastleInterface.h" #include "AdventureMapButton.h" #include "CAdvmapInterface.h" +#include "CAnimation.h" #include "../CCallback.h" #include "CGameInfo.h" #include "CHeroWindow.h" @@ -20,7 +21,7 @@ #include "../lib/map.h" #include #include -#include +#include #include #include #include @@ -52,45 +53,32 @@ int hordeToDwellingID(int bid)//helper, converts horde buiding ID into correspon } CBuildingRect::CBuildingRect(Structure *Str) - :moi(false), offset(0), str(Str) + :CShowableAnim(0, 0, Str->defName, CShowableAnim::FLAG_BASE), + moi(false), str(Str) { - def = CDefHandler::giveDef(Str->defName); - max = def->ourImages.size(); - if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette - { - for(std::vector::iterator i=def->ourImages.begin();i!=def->ourImages.end();i++) - { - SDL_SetColorKey(i->bitmap,SDL_SRCCOLORKEY,*((char*)i->bitmap->pixels)); - } - } + pos.x += str->pos.x + LOCPLINT->castleInt->pos.x; + pos.y += str->pos.y + LOCPLINT->castleInt->pos.y; + + if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette + for(size_t i=0; ipixels))); - pos.x = str->pos.x + LOCPLINT->castleInt->pos.x; - pos.y = str->pos.y + LOCPLINT->castleInt->pos.y; - pos.w = def->ourImages[0].bitmap->w; - pos.h = def->ourImages[0].bitmap->h; if(Str->ID<0 || (Str->ID>=27 && Str->ID<=29)) { area = border = NULL; return; } - border = BitmapHandler::loadBitmap(str->borderName); - if (border) - { - SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255)); - } - else + border = BitmapHandler::loadBitmap(str->borderName, true); + if (!border) { tlog2 << "Warning: no border for "<ID<areaName); //FIXME look up - if (area) - { - ;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255)); - } - else + area = BitmapHandler::loadBitmap(str->areaName); + if (!area) { tlog2 << "Warning: no area for "<ID<castleInt->hBuild==this) && !(indeterminate(down)) && - !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image - { - if(previousState && !down) + if( previousState && !down && area && (LOCPLINT->castleInt->hBuild==this) ) + if (!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image LOCPLINT->castleInt->buildingClicked(str->ID); - //ClickableL::clickLeft(down); - } } + void CBuildingRect::clickRight(tribool down, bool previousState) { if((!area) || (!((bool)down)) || (this!=LOCPLINT->castleInt->hBuild)) @@ -169,7 +154,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState) if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image { int bid = hordeToDwellingID(str->ID); - + CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second; assert(bld); @@ -186,11 +171,24 @@ void CBuildingRect::clickRight(tribool down, bool previousState) } } +void CBuildingRect::show(SDL_Surface *to) +{ + CShowableAnim::show(to); + + if(LOCPLINT->castleInt->hBuild == this && border) //if this this higlighted structure and has border we'll blit it + blitAtLoc(border,0,0,to); +} + +void CBuildingRect::showAll(SDL_Surface *to) +{ + show(to); +} + std::string getBuildingSubtitle(int tid, int bid)//hover text for building { const CGTownInstance * t = LOCPLINT->castleInt->town; bid = hordeToDwellingID(bid); - + if (bid<30)//non-dwellings - only buiding name return CGI->buildh->buildings[tid].find(bid)->second->Name(); else//dwellings - recruit %creature% @@ -214,27 +212,19 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent) } else //inside the area of this building { - if(LOCPLINT->castleInt->hBuild) //a building is hovered - { - if((*LOCPLINT->castleInt->hBuild)<(*this)) //set if we are on top - { - LOCPLINT->castleInt->hBuild = this; - GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID)); - } - } - else //no building hovered + if(! LOCPLINT->castleInt->hBuild //no building hovered + || (*LOCPLINT->castleInt->hBuild)<(*this)) //or we are on top { LOCPLINT->castleInt->hBuild = this; GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID)); } } } - //if(border) - // blitAt(border,pos.x,pos.y); } + void CHeroGSlot::hover (bool on) { - if(!on) + if(!on) { GH.statusbar->clear(); return; @@ -284,10 +274,6 @@ void CHeroGSlot::hover (bool on) GH.statusbar->print(temp); } -void CHeroGSlot::clickRight(tribool down, bool previousState) -{ -} - void CHeroGSlot::clickLeft(tribool down, bool previousState) { CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown; @@ -341,19 +327,10 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState) //} } -void CHeroGSlot::activate() -{ - activateLClick(); - activateRClick(); - activateHover(); -} - void CHeroGSlot::deactivate() { highlight = false; - deactivateLClick(); - deactivateRClick(); - deactivateHover(); + CIntObject::deactivate(); } void CHeroGSlot::show(SDL_Surface * to) @@ -544,7 +521,7 @@ void CCastleInterface::buildingClicked(int building) } } else - { + { enterMageGuild(); } break; @@ -572,8 +549,8 @@ void CCastleInterface::buildingClicked(int building) if(!vstd::contains(town->forbiddenBuildings, 26)) { LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[597], //Do you wish this to be the permanent home of the Grail? - std::vector(), - boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26), + std::vector(), + boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26), boost::bind(&CCastleInterface::enterHall, this), true); } else @@ -643,7 +620,7 @@ void CCastleInterface::buildingClicked(int building) GH.pushInt(new CUniversityWindow(town->garrisonHero, town)); else//no hero in town - default popup defaultBuildingClicked(building); - + break; default: defaultBuildingClicked(building); @@ -665,7 +642,7 @@ void CCastleInterface::buildingClicked(int building) LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[126], std::vector(), soundBase::sound_todo); break;//only visiting hero can use castle gates } - + std::vector availableTowns; std::vector Towns = LOCPLINT->cb->getTownsInfo(false); for(size_t i=0;igarrisonHero; else hero = NULL;//no hero - will trade with town garrison - + GH.pushInt ( new CTransformerWindow(hero, town) ); break; - + /*Dungeon*/ case 5: //Portal of Summoning if (town->creatures[CREATURES_PER_TOWN].second.empty()) //extra dwelling has no creatures in it LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30], std::vector(), soundBase::sound_todo); - else + else this->showRecruitmentWindow(CREATURES_PER_TOWN); break; /*Stronghold*/ case 6: //Ballista Yard @@ -828,30 +805,13 @@ void CCastleInterface::townChange() void CCastleInterface::show(SDL_Surface * to) { - count++; - if(count==5) - { - count=0; - animval++; - } - blitAt(cityBg,pos,to); //blit buildings for(size_t i=0;imax - buildings[i]->offset)) + buildings[i]->offset; - if(frame) - { - blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to); - blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to); - } - else - blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to); - - if(hBuild==buildings[i] && hBuild->border) //if this this higlighted structure and has border we'll blit it - blitAt(hBuild->border,hBuild->pos,to); + buildings[i]->showAll(to); } statusbar->show(to);//refreshing statusbar } @@ -992,7 +952,7 @@ void CCastleInterface::recreateBuildings() Structure * st = CGI->townh->structures[town->subID][20]; buildings.push_back(new CBuildingRect(st)); s.insert(std::pair(st->group,st->ID)); - isThereShip = true; + isThereShip = true; } } @@ -1012,13 +972,11 @@ void CCastleInterface::recreateBuildings() } if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5 { - vortex->offset = 10; - vortex->max = vortex->def->ourImages.size(); + vortex->set(0,10); } else { - vortex->offset = 0; - vortex->max = 10; + vortex->set(0,0,9); } } //code for the shipyard in the Castle @@ -1043,13 +1001,11 @@ void CCastleInterface::recreateBuildings() } if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel { - shipyard->offset = 1; - shipyard->max = shipyard->def->ourImages.size(); + shipyard->set(0,1); } else { - shipyard->offset = 0; - shipyard->max = 1; + shipyard->set(0,0,0); } } } @@ -1154,7 +1110,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState) descr +="\n"+CGI->generaltexth->allTexts[590]; summ = CGI->creh->creatures[crid]->growth; boost::algorithm::replace_first(descr,"%d", boost::lexical_cast(summ)); - + if ( level>=0 && levelgeneraltexth->artifNames[133] + " %+d",descr, summ * ci->town->valOfGlobalBonuses - (Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion + (Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion if(ci->town->town->hordeLvl[0]==level)//horde, x to summ if((bld.find(18)!=bld.end()) || (bld.find(19)!=bld.end())) @@ -1200,7 +1156,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState) }; if (bl.size()) summ+=AddToString (CGI->arth->artifacts[bl.front().id]->Name()+" %+d", descr, bl.totalValue()); - + //TODO: player bonuses if(bld.find(26)!=bld.end()) //grail - +50% to ALL growth @@ -1261,7 +1217,7 @@ void CCastleInterface::CTownInfo::hover(bool on) { std::string descr; if ( bid == 6 ) {} //empty "no fort" icon. no hover message - else + else if ( bid == 14 ) //marketplace/income icon descr = CGI->generaltexth->allTexts[255]; else @@ -1282,7 +1238,7 @@ void CCastleInterface::CTownInfo::clickLeft(tribool down, bool previousState) void CCastleInterface::CTownInfo::clickRight(tribool down, bool previousState) { if(down) - { + { if (( bid == 6 ) || ( bid == 14) ) return; CInfoPopup *mess = new CInfoPopup(); @@ -1414,7 +1370,7 @@ void CHallInterface::CBuildingBox::show(SDL_Surface * to) CCastleInterface *ci = LOCPLINT->castleInt; if (( (BID == 18) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[0]+37)))) || ( (BID == 24) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[1]+37)))) ) - blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to); + blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to); else blitAt(ci->bicons->ourImages[BID].bitmap,pos.x,pos.y,to); int pom, pom2=-1; @@ -1672,7 +1628,7 @@ CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mod CSDL_Ext::printAtMiddleWB(getTextForState(state),199,248,FONT_SMALL,50,zwykly,bitmap); CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->generaltexth->hcommands[7],pom),197,30,FONT_BIG,tytulowy,bitmap); - int resamount=0; + int resamount=0; for(int i=0;i<7;i++) { if(CGI->buildh->buildings[tid][bid]->resources[i]) @@ -1738,12 +1694,10 @@ CFortScreen::~CFortScreen() void CFortScreen::show( SDL_Surface * to) { blitAt(bg,pos,to); - static unsigned char anim = 1; for (int i=0; iblitPic(to,pos.x+positions[i].x+159,pos.y+positions[i].y+4,!(anim%4)); + crePics[i]->show(to); } - anim++; exit->show(to); resdatabar->show(to); GH.statusbar->show(to); @@ -1775,7 +1729,7 @@ void CFortScreen::close() CFortScreen::CFortScreen( CCastleInterface * owner ) { - if (owner->town->creatures.size() > CREATURES_PER_TOWN + if (owner->town->creatures.size() > CREATURES_PER_TOWN && owner->town->creatures[CREATURES_PER_TOWN].second.size() )//dungeon with active portal fortSize = CREATURES_PER_TOWN+1; else @@ -1809,11 +1763,11 @@ void CFortScreen::draw( CCastleInterface * owner, bool first) bg2 = BitmapHandler::loadBitmap("TPCASTL7.bmp"); else bg2 = BitmapHandler::loadBitmap("TPCASTL8.bmp"); - + SDL_Surface *icons = BitmapHandler::loadBitmap("ZPCAINFO.bmp"); SDL_SetColorKey(icons,SDL_SRCCOLORKEY,SDL_MapRGB(icons->format,0,255,255)); graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID); - bg = SDL_ConvertSurface(bg2,screen->format,0); + bg = SDL_ConvertSurface(bg2,screen->format,0); SDL_FreeSurface(bg2); printAtMiddle(CGI->buildh->buildings[owner->town->subID][owner->town->fortLevel()+6]->Name(),400,13,FONT_MEDIUM,zwykly,bg); for(int i=0;icenter(); resdatabar = new CMinorResDataBar; - pos = owner->pos; resdatabar->pos.x += pos.x; resdatabar->pos.y += pos.y; - bg = BitmapHandler::loadBitmap("TPMAGE.bmp"); LOCPLINT->castleInt->statusbar->clear(); - exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN); + + exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this), 748, 556,"TPMAGE1.DEF",SDLK_RETURN); exit->assignedKeys.insert(SDLK_ESCAPE); - scrolls2 = CDefHandler::giveDefEss("TPMAGES.DEF"); + CAnimation scrolls("TPMAGES.DEF"); + scrolls.load(); + SDL_Surface *view = BitmapHandler::loadBitmap(graphics->guildBgs[owner->town->subID]); SDL_SetColorKey(view,SDL_SRCCOLORKEY,SDL_MapRGB(view->format,0,255,255)); + blitAt(view,332,76,*bg); + SDL_FreeSurface(view); + positions.resize(5); positions[0] += genRect(61,83,222,445), genRect(61,83,312,445), genRect(61,83,402,445), genRect(61,83,520,445), genRect(61,83,610,445), genRect(61,83,700,445); positions[1] += genRect(61,83,48,53), genRect(61,83,48,147), genRect(61,83,48,241), genRect(61,83,48,335), genRect(61,83,48,429); positions[2] += genRect(61,83,570,82), genRect(61,83,672,82), genRect(61,83,570,157), genRect(61,83,672,157); positions[3] += genRect(61,83,183,42), genRect(61,83,183,148), genRect(61,83,183,253); positions[4] += genRect(61,83,491,325), genRect(61,83,591,325); - blitAt(view,332,76,bg); + for(size_t i=0; itown->town->mageLevel; i++) { size_t sp = owner->town->spellsAtLevel(i+1,false); //spell at level with -1 hmmm? @@ -1931,30 +1893,27 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner) { if(itown->mageGuildLevel() && owner->town->spells[i].size()>j) { - spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]])); - spells[spells.size()-1].pos = positions[i][j]; - blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],bg); + spells.push_back( new Scroll(&CGI->spellh->spells[owner->town->spells[i][j]])); + spells[spells.size()-1]->pos = positions[i][j]; + blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],*bg); } else { - blitAt(scrolls2->ourImages[1].bitmap,positions[i][j],bg); + blitAt(scrolls.image(1),positions[i][j],*bg); } } } - SDL_FreeSurface(view); + for(size_t i=0;ipos.x += pos.x; + spells[i]->pos.y += pos.y; } - delete scrolls2; } CMageGuildScreen::~CMageGuildScreen() { - delete exit; - SDL_FreeSurface(bg); - delete resdatabar; + } void CMageGuildScreen::close() @@ -1962,30 +1921,10 @@ void CMageGuildScreen::close() GH.popIntTotally(this); } -void CMageGuildScreen::show(SDL_Surface * to) +CMageGuildScreen::Scroll::Scroll(CSpell *Spell) + :spell(Spell) { - blitAt(bg,pos,to); - resdatabar->show(to); - GH.statusbar->show(to); - exit->show(to); -} - -void CMageGuildScreen::activate() -{ - exit->activate(); - for(size_t i=0;ideactivate(); - for(size_t i=0;iprint(spell->name); else @@ -2027,66 +1965,39 @@ void CMageGuildScreen::Scroll::hover(bool on) CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid) { - SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPSMITH.bmp"); - SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255)); - graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID); - bmp = SDL_ConvertSurface(bg2,screen->format,0); - SDL_FreeSurface(bg2); - bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp"); - blitAt(bg2,64,50,bmp); - SDL_FreeSurface(bg2); + OBJ_CONSTRUCTION_CAPTURING_ALL; +// SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255)); + bmp = new CPicture("TPSMITH"); + bmp->colorizeAndConvert(LOCPLINT->playerID); + + pos = bmp->center(); + + SDL_Surface *bg = BitmapHandler::loadBitmap("TPSMITBK.bmp"); + blitAt(bg,64,50,*bmp); + SDL_FreeSurface(bg); - CCreatureAnimation cra(CGI->creh->creatures[creMachineID]->animDefName); - cra.nextFrameMiddle(bmp,170,120,true,0,false); + CCreatureAnim cra(170, 120, CGI->creh->creatures[creMachineID]->animDefName); char pom[75]; sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID]->nameSing.c_str()); //build a new ... - printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,bmp); - printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,bmp); //resource cost + printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,*bmp); + printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,*bmp); //resource cost SDL_itoa(CGI->arth->artifacts[aid]->price,pom,10); - printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,bmp); + printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,*bmp); - pos.w = bmp->w; - pos.h = bmp->h; - pos.x = screen->w/2 - pos.w/2; - pos.y = screen->h/2 - pos.h/2; - - buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF",SDLK_RETURN); - cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF",SDLK_ESCAPE); + buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 42, 312,"IBUY30.DEF",SDLK_RETURN); + cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 224, 312,"ICANCEL.DEF",SDLK_ESCAPE); if(possible) buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid); else - buy->bitmapOffset = 2; + buy->block(2); - blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp); -} - -void CBlacksmithDialog::show( SDL_Surface * to ) -{ - blitAt(bmp,pos,to); - buy->show(to); - cancel->show(to); -} - -void CBlacksmithDialog::activate() -{ - if(!buy->bitmapOffset) - buy->activate(); - cancel->activate(); -} - -void CBlacksmithDialog::deactivate() -{ - if(!buy->bitmapOffset) - buy->deactivate(); - cancel->deactivate(); + blitAt(graphics->resources32->ourImages[6].bitmap,148,244,*bmp); } CBlacksmithDialog::~CBlacksmithDialog() { - SDL_FreeSurface(bmp); - delete cancel; - delete buy; + } void CBlacksmithDialog::close() diff --git a/client/CCastleInterface.h b/client/CCastleInterface.h index 72a28bf28..49757af28 100644 --- a/client/CCastleInterface.h +++ b/client/CCastleInterface.h @@ -5,6 +5,7 @@ #include "../global.h" #include +#include "CAnimation.h" #include "GUIBase.h" #include "../hch/CMusicBase.h" //#include "boost/tuple/tuple.hpp" @@ -19,6 +20,7 @@ class CStatusBar; class CTownList; class CRecruitmentWindow; class CTransformerWindow; +class CPicture; class CCreaturePic; class CMinorResDataBar; @@ -32,13 +34,11 @@ class CMinorResDataBar; * */ -class CBuildingRect : public CIntObject +class CBuildingRect : public CShowableAnim { public: bool moi; //motion interested is active - int offset, max; //first and last animation frame Structure* str; - CDefHandler* def; SDL_Surface* border; SDL_Surface* area; CBuildingRect(Structure *Str); //c-tor @@ -50,6 +50,8 @@ public: void clickLeft(tribool down, bool previousState); void clickRight(tribool down, bool previousState); void mouseMoved (const SDL_MouseMotionEvent & sEvent); + void show(SDL_Surface *to); + void showAll(SDL_Surface *to); }; class CHeroGSlot : public CIntObject @@ -63,9 +65,7 @@ public: void setHighlight(bool on); void hover (bool on); - void clickRight(tribool down, bool previousState); void clickLeft(tribool down, bool previousState); - void activate(); void deactivate(); void show(SDL_Surface * to); CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor @@ -240,40 +240,35 @@ public: public: CSpell *spell; - Scroll(CSpell *Spell):spell(Spell){used = LCLICK | RCLICK | HOVER;}; + Scroll(CSpell *Spell); void clickLeft(tribool down, bool previousState); void clickRight(tribool down, bool previousState); void hover(bool on); }; std::vector > positions; - SDL_Surface *bg; - CDefEssential *scrolls, *scrolls2; + CPicture *bg; AdventureMapButton *exit; - std::vector spells; + std::vector spells; CMinorResDataBar * resdatabar; CMageGuildScreen(CCastleInterface * owner); //c-tor ~CMageGuildScreen(); //d-tor void close(); - void show(SDL_Surface * to); - void activate(); - void deactivate(); + }; class CBlacksmithDialog : public CIntObject { public: AdventureMapButton *buy, *cancel; - SDL_Surface *bmp; //background + CPicture *bmp; //background + CCreatureAnim * anim; CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid); //c-tor ~CBlacksmithDialog(); //d-tor void close(); - void show(SDL_Surface * to); - void activate(); - void deactivate(); }; #endif // __CCASTLEINTERFACE_H__ diff --git a/client/CMessage.cpp b/client/CMessage.cpp index e6221bcb9..4f5aa66d7 100644 --- a/client/CMessage.cpp +++ b/client/CMessage.cpp @@ -2,7 +2,7 @@ #include "CMessage.h" #include "SDL_ttf.h" #include "../hch/CDefHandler.h" -#include "../hch/CAnimation.h" +#include "CAnimation.h" #include "CGameInfo.h" #include "SDL_Extensions.h" #include "../hch/CLodHandler.h" diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index 5ca5a9635..a2744b880 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -9,7 +9,7 @@ #include "SDL_Extensions.h" #include "CGameInfo.h" #include "CCursorHandler.h" -#include "../hch/CAnimation.h" +#include "CAnimation.h" #include "../hch/CDefHandler.h" #include "../hch/CDefObjInfoHandler.h" #include "../hch/CGeneralTextHandler.h" @@ -2097,8 +2097,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero) if(!btns[0]) return; - if(!onlyHero && pi.defaultCastle() != -1 //fixed tow - || SEL->isGuest() && s.color != playerColor) //or not our player + if( (!onlyHero && pi.defaultCastle() != -1) //fixed tow + || (SEL->isGuest() && s.color != playerColor)) //or not our player { btns[0]->disable(); btns[1]->disable(); @@ -2109,8 +2109,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero) btns[1]->enable(active); } - if(pi.defaultHero() != -1 || !s.human || s.castle < 0 //fixed hero - || SEL->isGuest() && s.color != playerColor)//or not our player + if( (pi.defaultHero() != -1 || !s.human || s.castle < 0) //fixed hero + || (SEL->isGuest() && s.color != playerColor))//or not our player { btns[2]->disable(); btns[3]->disable(); @@ -3128,7 +3128,7 @@ void CBonusSelection::CRegion::clickRight( tribool down, bool previousState ) void CBonusSelection::CRegion::show( SDL_Surface * to ) { - const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber]; + //const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber]; if (!accessible) { //show as striped diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index bf6d94ace..5a40ae106 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -15,7 +15,7 @@ #include "CConfigHandler.h" #include "CCreatureAnimation.h" #include "Graphics.h" -#include "../hch/CAnimation.h" +#include "CAnimation.h" #include "../hch/CArtHandler.h" #include "../hch/CBuildingHandler.h" #include "../hch/CGeneralTextHandler.h" @@ -1632,37 +1632,37 @@ int CTownList::size() return LOCPLINT->towns.size(); } -CCreaturePic::CCreaturePic(const CCreature *cre, bool Big) +CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool Animated) :c(cre),big(Big) { - anim = new CCreatureAnimation(cre->animDefName); + OBJ_CONSTRUCTION_CAPTURING_ALL; + pos.x+=x; + pos.y+=y; + + x = 225 - (c->isDoubleWide()?63:78); + y = 225 - (big?75:65); + + anim = new CCreatureAnim(0,0, cre->animDefName); + anim->movePic(x,y); + anim->pos.w = 100; + anim->pos.h = big?130:120; } + CCreaturePic::~CCreaturePic() { - delete anim; + } -int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame) + +void CCreaturePic::show(SDL_Surface *to) { - SDL_Rect dst; if(big) - { - blitAt(graphics->backgrounds[c->faction],x,y,to);//curx-50,pos.y+130-65); - dst = genRect(130,100,x,y); - } + blitAtLoc(graphics->backgrounds[c->faction],0,0,to); else - { - blitAt(graphics->backgroundsm[c->faction],x,y,to);//curx-50,pos.y+130-65); - dst = genRect(120,100,x,y); - } - if(c->isDoubleWide()) - x-=15; - return anim->nextFrameMiddle(to,x+78,y+(big ? 55 : 45),true,0,nextFrame,false,false,&dst); -} -SDL_Surface * CCreaturePic::getPic(bool nextFrame) -{ - //TODO: write - return NULL; + blitAtLoc(graphics->backgroundsm[c->faction],0,0,to); + + CIntObject::show(to); } + void CRecruitmentWindow::close() { GH.popIntTotally(this); @@ -1783,7 +1783,6 @@ void CRecruitmentWindow::deactivate() void CRecruitmentWindow::show(SDL_Surface * to) { - static char animCounter=0; //animation counter - for determining appropriate animation frame to be shown blitAt(bitmap,pos.x,pos.y,to); buy->show(to); max->show(to); @@ -1809,14 +1808,9 @@ void CRecruitmentWindow::show(SDL_Surface * to) curx+=32+16;//size of bitmap + distance between them } - curx = pos.x + 192 + CREATURE_WIDTH - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2); for(int i=0; iblitPic(to, curx-50, pos.y+130-65, !(animCounter%4)); - curx += TOTAL_CREATURE_WIDTH; - } + creatures[i].pic->show(to); - ++animCounter; bar->show(to); } @@ -1854,17 +1848,18 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co drawBorder(bitmap,289,312,66,34,int3(173,142,66)); //border for creatures - int curx = 192 + 51 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2); + int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2); for(int i=0;icreh->creatures[creatures[i].ID]); curx += TOTAL_CREATURE_WIDTH; } @@ -1902,8 +1897,7 @@ void CRecruitmentWindow::initCres() cur.amount = dwelling->creatures[i].first; cur.ID = dwelling->creatures[i].second[j]; - const CCreature *cre = CGI->creh->creatures[cur.ID]; - cur.pic = new CCreaturePic(cre); + CCreature * cre= CGI->creh->creatures[cur.ID]; for(int k=0; kcost.size(); k++) if(cre->cost[k]) @@ -1948,8 +1942,8 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),0,sliderPositions,val,true); a1 = max-val; a2 = val; - anim = new CCreaturePic(CGI->creh->creatures[cid]); - anim->anim->setType(1); + animLeft = new CCreaturePic(pos.x+20, pos.y+54, CGI->creh->creatures[cid], true, false); + animRight = new CCreaturePic(pos.x+177, pos.y+54, CGI->creh->creatures[cid], true, false); std::string title = CGI->generaltexth->allTexts[256]; boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid]->namePl); @@ -1962,7 +1956,8 @@ CSplitWindow::~CSplitWindow() //d-tor delete ok; delete cancel; delete slider; - delete anim; + delete animLeft; + delete animRight; } void CSplitWindow::activate() @@ -2010,8 +2005,8 @@ void CSplitWindow::show(SDL_Surface * to) slider->show(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); - anim->blitPic(to,pos.x+20,pos.y+54,false); - anim->blitPic(to,pos.x+177,pos.y+54,false); + animLeft->show(to); + animRight->show(to); } void CSplitWindow::keyPressed (const SDL_KeyboardEvent & key) @@ -2077,9 +2072,7 @@ void CSplitWindow::clickLeft(tribool down, bool previousState) void CCreInfoWindow::show(SDL_Surface * to) { blitAt(*bitmap,pos.x,pos.y,to); - anim->blitPic(to,pos.x+21,pos.y+48,(type) && !(anf%4)); - if(++anf==4) - anf=0; + anim->show(to); if(count.size()) printTo(count.c_str(),pos.x+114,pos.y+174,FONT_TIMES,zwykly,to); if(upgrade) @@ -2157,7 +2150,6 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi if(printed >= 3) //we can fit only 3 effects break; } - //print current health printLine(5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft); } @@ -2188,19 +2180,13 @@ void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int else finalNode = cre; - anf = 0; c = cre; bitmap = new CPicture("CRSTKPU.bmp"); bitmap->colorizeAndConvert(LOCPLINT->playerID); pos = bitmap->center(); - { - BLOCK_CAPTURING; - anim = new CCreaturePic(c); - } - - if(!type) anim->anim->setType(2); + anim = new CCreaturePic(21, 48, c); count = boost::lexical_cast(creatureCount); @@ -2253,7 +2239,6 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount) CCreInfoWindow::~CCreInfoWindow() { - delete anim; for(int i=0; i &poss, bool Left, EType typ genRect(h, w, x + dx, y + 2*dy); if(!Left) + { BOOST_FOREACH(Rect &r, poss) r.x += leftToRightOffset; + } } } @@ -3269,7 +3261,7 @@ void CMarketplaceWindow::selectionChanged(bool side) bool CMarketplaceWindow::printButtonFor(EMarketMode M) const { - return market->allowsTrade(M) && M != mode && (hero || M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE); + return market->allowsTrade(M) && M != mode && (hero || ( M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE )); } void CMarketplaceWindow::garrisonChanged() @@ -6013,16 +6005,9 @@ CHillFortWindow::~CHillFortWindow() void CHillFortWindow::activate() { CIntObject::activate(); - garr->activate(); GH.statusbar = bar; } -void CHillFortWindow::deactivate() -{ - CIntObject::deactivate(); - garr->deactivate(); -} - void CHillFortWindow::updateGarrisons() { diff --git a/client/GUIClasses.h b/client/GUIClasses.h index 3f16cf58d..2d03753ee 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -42,7 +42,7 @@ class SComponent; class CCreature; struct SDL_Surface; struct CPath; -class CCreatureAnimation; +class CCreatureAnim; class CSelectableComponent; class CCreatureSet; class CGObjectInstance; @@ -435,16 +435,18 @@ public: int size(); //how many elements do we have }; -class CCreaturePic //draws picture with creature on background, use nextFrame=true to get animation +class CCreaturePic : public CIntObject //draws picture with creature on background, use Animated=true to get animation { -public: +private: const CCreature *c; //which creature's picture bool big; //big => 100x130; !big => 100x120 - CCreatureAnimation *anim; //displayed animation - CCreaturePic(const CCreature *cre, bool Big=true); //c-tor + CCreatureAnim *anim; //displayed animation + +public: + CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor ~CCreaturePic(); //d-tor - int blitPic(SDL_Surface *to, int x, int y, bool nextFrame); //prints creature on screen - SDL_Surface * getPic(bool nextFrame); //returns frame of animation + void show(SDL_Surface *to); //prints creature on screen + }; class CRecruitmentWindow : public CIntObject @@ -496,7 +498,7 @@ class CSplitWindow : public CIntObject public: CGarrisonInt *gar; CSlider *slider; - CCreaturePic *anim; //creature's animation + CCreaturePic *animLeft, *animRight; //creature's animation AdventureMapButton *ok, *cancel; SDL_Surface *bitmap; //background int a1, a2, c; //TODO: comment me @@ -538,6 +540,7 @@ class CMinorResDataBar : public CIntObject public: SDL_Surface *bg; //background bitmap void show(SDL_Surface * to); + void showAll(SDL_Surface * to); CMinorResDataBar(); //c-tor ~CMinorResDataBar(); //d-tor }; @@ -865,7 +868,6 @@ public: //bool active; //TODO: comment me int type;//0 - rclick popup; 1 - normal window CPicture *bitmap; //background - char anf; //animation counter std::string count; //creature count in text format boost::function dsm; //dismiss button callback @@ -1082,7 +1084,7 @@ class CUniversityWindow : public CIntObject public: int ID;//id of selected skill CUniversityWindow * parent; - + void showAll(SDL_Surface * to); void clickLeft(tribool down, bool previousState); void clickRight(tribool down, bool previousState); @@ -1094,14 +1096,14 @@ class CUniversityWindow : public CIntObject public: const CGHeroInstance *hero; const IMarket * market; - + CPicture * green, * yellow, * red;//colored bars near skills CPicture *bg; //background std::vector items; AdventureMapButton *cancel; CGStatusBar *bar; - + CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); //c-tor ~CUniversityWindow(); //d-tor }; @@ -1136,13 +1138,12 @@ public: const CGHeroInstance * hero; std::vector currState;//current state of slot - to avoid calls to getState or updating buttons std::vector > costs;// costs [slot ID] [resource ID] = resource count for upgrade - std::vector totalSumm; // totalSum[resource ID] = value + std::vector totalSumm; // totalSum[resource ID] = value CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor ~CHillFortWindow(); //d-tor - + void activate(); - void deactivate(); void showAll (SDL_Surface *to); std::string getDefForSlot(int slot);//return def name for this slot std::string getTextForSlot(int slot);//return hover text for this slot diff --git a/client/Makefile.am b/client/Makefile.am index 22da5fbe9..1d3594e2f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -13,8 +13,6 @@ vcmiclient_SOURCES = \ ../CThreadHelper.h \ ../StartInfo.h \ ../global.h \ - ../hch/CAnimation.h \ - ../hch/CAnimation.cpp \ ../hch/CBuildingHandler.h \ ../hch/CDefHandler.cpp \ ../hch/CDefHandler.h \ @@ -39,6 +37,8 @@ vcmiclient_SOURCES = \ AdventureMapButton.h \ CAdvmapInterface.cpp \ CAdvmapInterface.h \ + CAnimation.h \ + CAnimation.cpp \ CBattleInterface.cpp \ CBattleInterface.h \ CBitmapHandler.cpp \ diff --git a/client/Makefile.in b/client/Makefile.in index d39d1b07a..ac24c5424 100644 --- a/client/Makefile.in +++ b/client/Makefile.in @@ -59,7 +59,6 @@ PROGRAMS = $(bin_PROGRAMS) am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \ vcmiclient-CGameInterface.$(OBJEXT) \ vcmiclient-CThreadHelper.$(OBJEXT) \ - vcmiclient-CAnimation.$(OBJEXT) \ vcmiclient-CDefHandler.$(OBJEXT) \ vcmiclient-CMusicHandler.$(OBJEXT) \ vcmiclient-CSndHandler.$(OBJEXT) \ @@ -67,6 +66,7 @@ am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \ vcmiclient-CMapInfo.$(OBJEXT) \ vcmiclient-AdventureMapButton.$(OBJEXT) \ vcmiclient-CAdvmapInterface.$(OBJEXT) \ + vcmiclient-CAnimation.$(OBJEXT) \ vcmiclient-CBattleInterface.$(OBJEXT) \ vcmiclient-CBitmapHandler.$(OBJEXT) \ vcmiclient-CCastleInterface.$(OBJEXT) \ @@ -282,8 +282,6 @@ vcmiclient_SOURCES = \ ../CThreadHelper.h \ ../StartInfo.h \ ../global.h \ - ../hch/CAnimation.h \ - ../hch/CAnimation.cpp \ ../hch/CBuildingHandler.h \ ../hch/CDefHandler.cpp \ ../hch/CDefHandler.h \ @@ -308,6 +306,8 @@ vcmiclient_SOURCES = \ AdventureMapButton.h \ CAdvmapInterface.cpp \ CAdvmapInterface.h \ + CAnimation.h \ + CAnimation.cpp \ CBattleInterface.cpp \ CBattleInterface.h \ CBitmapHandler.cpp \ @@ -546,22 +546,6 @@ vcmiclient-CThreadHelper.obj: ../CThreadHelper.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CThreadHelper.obj `if test -f '../CThreadHelper.cpp'; then $(CYGPATH_W) '../CThreadHelper.cpp'; else $(CYGPATH_W) '$(srcdir)/../CThreadHelper.cpp'; fi` -vcmiclient-CAnimation.o: ../hch/CAnimation.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po -@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp - -vcmiclient-CAnimation.obj: ../hch/CAnimation.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po -@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi` - vcmiclient-CDefHandler.o: ../hch/CDefHandler.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CDefHandler.o -MD -MP -MF $(DEPDIR)/vcmiclient-CDefHandler.Tpo -c -o vcmiclient-CDefHandler.o `test -f '../hch/CDefHandler.cpp' || echo '$(srcdir)/'`../hch/CDefHandler.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CDefHandler.Tpo $(DEPDIR)/vcmiclient-CDefHandler.Po @@ -674,6 +658,22 @@ vcmiclient-CAdvmapInterface.obj: CAdvmapInterface.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAdvmapInterface.obj `if test -f 'CAdvmapInterface.cpp'; then $(CYGPATH_W) 'CAdvmapInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/CAdvmapInterface.cpp'; fi` +vcmiclient-CAnimation.o: CAnimation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp + +vcmiclient-CAnimation.obj: CAnimation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi` + vcmiclient-CBattleInterface.o: CBattleInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CBattleInterface.o -MD -MP -MF $(DEPDIR)/vcmiclient-CBattleInterface.Tpo -c -o vcmiclient-CBattleInterface.o `test -f 'CBattleInterface.cpp' || echo '$(srcdir)/'`CBattleInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CBattleInterface.Tpo $(DEPDIR)/vcmiclient-CBattleInterface.Po diff --git a/hch/CLodHandler.cpp b/hch/CLodHandler.cpp index e7264ae6a..832ca7d8d 100644 --- a/hch/CLodHandler.cpp +++ b/hch/CLodHandler.cpp @@ -91,19 +91,23 @@ unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType typ if (ourEntry.offset<0) //file is in the sprites/ folder; no compression { int result; - unsigned char * outp = new unsigned char[ourEntry.realSize]; + outp = new unsigned char[ourEntry.realSize]; FILE * f = fopen((myDir + "/" + ourEntry.realName).c_str(), "rb"); - if (f) { + if (f) + { result = fread(outp,1,ourEntry.realSize,f); fclose(f); - } else + } + else result = -1; mutex->unlock(); - if(result<0) { + if(result<0) + { tlog1<<"Error in file reading: " << myDir << "/" << ourEntry.name << std::endl; delete[] outp; return NULL; - } else + } + else return outp; } else if (ourEntry.size==0) //file is not compressed From 73a4c2e446ccec2bd416a72d83b1f0cd6617f273 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 18 Nov 2010 13:34:21 +0000 Subject: [PATCH 5/5] - missed Hill Fort fixes - compile fix --- client/CAnimation.cpp | 128 +++++++++++++++++++++++------------------- client/GUIClasses.cpp | 4 +- 2 files changed, 73 insertions(+), 59 deletions(-) diff --git a/client/CAnimation.cpp b/client/CAnimation.cpp index ebfb98bd8..8620e7999 100644 --- a/client/CAnimation.cpp +++ b/client/CAnimation.cpp @@ -47,23 +47,20 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette { SDL_Surface * ret=NULL; - unsigned int BaseOffset, - SpriteWidth, SpriteHeight, //format of sprite - TotalRowLength, // length of read segment - add, FullHeight,FullWidth, - RowAdd, - prSize, - defType2; - int LeftMargin, RightMargin, TopMargin, BottomMargin; + unsigned int DefFormat, // format in which pixel data of sprite is encoded + FullHeight,FullWidth, // full width and height of sprite including borders + SpriteWidth, SpriteHeight, // width and height of encoded sprite + TotalRowLength, + RowAdd, add, + BaseOffset; - unsigned char SegmentType; + int LeftMargin, RightMargin, // position of 1st stored in sprite pixel on surface + TopMargin, BottomMargin; - BaseOffset = 0; - SSpriteDef sd = * reinterpret_cast(FDef + BaseOffset); + SSpriteDef sd = * reinterpret_cast(FDef); - prSize = SDL_SwapLE32(sd.prSize); - defType2 = SDL_SwapLE32(sd.defType2); + DefFormat = SDL_SwapLE32(sd.defType2); FullWidth = SDL_SwapLE32(sd.FullWidth); FullHeight = SDL_SwapLE32(sd.FullHeight); SpriteWidth = SDL_SwapLE32(sd.SpriteWidth); @@ -73,8 +70,6 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette RightMargin = FullWidth - SpriteWidth - LeftMargin; BottomMargin = FullHeight - SpriteHeight - TopMargin; - //if(LeftMargin + RightMargin < 0) - // SpriteWidth += LeftMargin + RightMargin; //ugly construction... TODO: check how to do it nicer if (LeftMargin<0) SpriteWidth+=LeftMargin; if (RightMargin<0) @@ -86,9 +81,8 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette add=0; ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0); - //int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str())); - BaseOffset += sizeof(SSpriteDef); + BaseOffset = sizeof(SSpriteDef); int BaseOffsetor = BaseOffset; for (int i=0; i<256; ++i) @@ -101,65 +95,75 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette (*(ret->format->palette->colors+i))=pr; } - int ftcp=0; - // If there's a margin anywhere, just blank out the whole surface. if (TopMargin > 0 || BottomMargin > 0 || LeftMargin > 0 || RightMargin > 0) { memset( reinterpret_cast(ret->pixels), 0, FullHeight*FullWidth); } + int current=0;//current pixel on output surface + // Skip top margin if (TopMargin > 0) - ftcp += TopMargin*(FullWidth+add); + current += TopMargin*(FullWidth+add); - switch (defType2) + switch (DefFormat) { + //pixel data is not compressed, copy each line to surface case 0: { for (unsigned int i=0; i0) - ftcp += LeftMargin; + current += LeftMargin; - memcpy(reinterpret_cast(ret->pixels)+ftcp, &FDef[BaseOffset], SpriteWidth); - ftcp += SpriteWidth; + memcpy(reinterpret_cast(ret->pixels)+current, &FDef[BaseOffset], SpriteWidth); + current += SpriteWidth; BaseOffset += SpriteWidth; if (RightMargin>0) - ftcp += RightMargin; + current += RightMargin; } } break; + // RLE encoding: + // read offset of pixel data of each line + // for each line + // read type and size + // if type is 0xff + // no encoding, copy to output + // else + // RLE: set size pixels to type + // do this until all line is parsed case 1: { + //for each line we have offset of pixel data const unsigned int * RWEntriesLoc = reinterpret_cast(FDef+BaseOffset); BaseOffset += sizeof(int) * SpriteHeight; + for (unsigned int i=0; i0) - ftcp += LeftMargin; + current += LeftMargin; TotalRowLength=0; do { - unsigned int SegmentLength; - - SegmentType=FDef[BaseOffset++]; - SegmentLength=FDef[BaseOffset++] + 1; + unsigned char SegmentType=FDef[BaseOffset++]; + unsigned int SegmentLength=FDef[BaseOffset++] + 1; if (SegmentType==0xFF) { - memcpy(reinterpret_cast(ret->pixels)+ftcp, FDef + BaseOffset, SegmentLength); + memcpy(reinterpret_cast(ret->pixels)+current, FDef + BaseOffset, SegmentLength); BaseOffset+=SegmentLength; } else { - memset(reinterpret_cast(ret->pixels)+ftcp, SegmentType, SegmentLength); + memset(reinterpret_cast(ret->pixels)+current, SegmentType, SegmentLength); } - ftcp += SegmentLength; + current += SegmentLength; TotalRowLength += SegmentLength; } while (TotalRowLength0) - ftcp += RightMargin; + current += RightMargin; if (add>0) - ftcp += add+RowAdd; + current += add+RowAdd; } } break; + // Something like RLE + // read base offset + // for each line + // read type, set code and value + // if code is 7 + // copy value pixels + // else + // set value pixels to code case 2: { BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor)); for (unsigned int i=0; i0) - ftcp += LeftMargin; + current += LeftMargin; TotalRowLength=0; do { - SegmentType=FDef[BaseOffset++]; + unsigned char SegmentType=FDef[BaseOffset++]; unsigned char code = SegmentType / 32; unsigned char value = (SegmentType & 31) + 1; if (code==7) { - memcpy(reinterpret_cast(ret->pixels)+ftcp, &FDef[BaseOffset], value); - ftcp += value; + memcpy(reinterpret_cast(ret->pixels)+current, &FDef[BaseOffset], value); + current += value; BaseOffset += value; } else { - memset(reinterpret_cast(ret->pixels)+ftcp, code, value); - ftcp += value; + memset(reinterpret_cast(ret->pixels)+current, code, value); + current += value; } TotalRowLength+=value; } while (TotalRowLength0) - ftcp += RightMargin; + current += RightMargin; RowAdd=SpriteWidth-TotalRowLength; if (add>0) - ftcp += add+RowAdd; + current += add+RowAdd; } } break; + //combo of 1st and 2nd: + // offset for each line + // code and value combined in 1 byte case 3: { for (unsigned int i=0; i0) - ftcp += LeftMargin; + current += LeftMargin; TotalRowLength=0; do { - SegmentType=FDef[BaseOffset++]; + unsigned char SegmentType=FDef[BaseOffset++]; unsigned char code = SegmentType / 32; unsigned char value = (SegmentType & 31) + 1; @@ -239,26 +253,26 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette if (code==7) { - memcpy((ui8*)ret->pixels + ftcp, FDef + BaseOffset, len); - ftcp += len; + memcpy((ui8*)ret->pixels + current, FDef + BaseOffset, len); + current += len; BaseOffset += len; } else { - memset((ui8*)ret->pixels + ftcp, code, len); - ftcp += len; + memset((ui8*)ret->pixels + current, code, len); + current += len; } TotalRowLength+=( LeftMargin>=0 ? value : value+LeftMargin ); } while (TotalRowLength0) - ftcp += RightMargin; + current += RightMargin; RowAdd=SpriteWidth-TotalRowLength; if (add>0) - ftcp += add+RowAdd; + current += add+RowAdd; } } break; @@ -286,12 +300,12 @@ CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL) { static SDL_Color H3Palette[8] = {{ 0, 0, 0, 255}, { 0, 0, 0, 192}, - { 0, 0, 0, 128}, + /* 5 shadow colors */ { 0, 0, 0, 128}, { 0, 0, 0, 64}, { 0, 0, 0, 32}, {255, 255, 0, 255}, - {255, 255, 0, 255}, - {255, 255, 0, 255}};//H3 palette for shadow\selection highlight + /* 3 selection highlight color */{255, 255, 0, 255}, + {255, 255, 0, 255}}; data = spriteh->giveFile(Name, FILE_ANIMATION, &datasize); if (!data) @@ -323,9 +337,9 @@ CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL) for (unsigned int i=0; ibg,Point(108,60),hero,NULL); + garr = new CGarrisonInt(108, 60, 18, Point(),bg->bg,Point(108,60),hero,NULL); updateGarrisons(); } CHillFortWindow::~CHillFortWindow() { - delete garr; + } void CHillFortWindow::activate()