1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

* major optimization of infoBar drawing

* new day animation (TODO: dorobic zeby pierwsza klatka wchodzila - wkrotce sie tym zajme)
* some stuff for selection window
* minor improvements
This commit is contained in:
Michał W. Urbańczyk
2007-12-19 00:06:51 +00:00
parent e12976a9fe
commit 6cd90195f4
4 changed files with 329 additions and 50 deletions

View File

@@ -16,6 +16,7 @@
#include <boost/algorithm/string/replace.hpp>
#include "CLua.h"
#include "hch/CHeroHandler.h"
#include <sstream>
extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
using namespace boost::logic;
@@ -1173,22 +1174,101 @@ void CResDataBar::draw()
}
CInfoBar::CInfoBar()
{
toNextTick = mode = pom = -1;
pos.x=605;
pos.y=389;
pos.w=194;
pos.h=186;
day = CGI->spriteh->giveDef("NEWDAY.DEF");
week1 = CGI->spriteh->giveDef("NEWWEEK1.DEF");
week2 = CGI->spriteh->giveDef("NEWWEEK2.DEF");
week3 = CGI->spriteh->giveDef("NEWWEEK3.DEF");
week4 = CGI->spriteh->giveDef("NEWWEEK4.DEF");
}
void CInfoBar::draw(void * specific)
CInfoBar::~CInfoBar()
{
//if (!specific)
// specific = LOCPLINT->adventureInt->selection.selected;
SDL_Surface * todr = LOCPLINT->infoWin(specific);
if (!todr)
return;
blitAt(todr,pos.x,pos.y);
//SDL_Flip(ekran);
SDL_FreeSurface(todr);
delete day;
delete week1;
delete week2;
delete week3;
delete week4;
}
void CInfoBar::draw(const CGObjectInstance * specific)
{
if (mode==1)
{
//blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
return;
}
else if (mode==2)
{
mode = -1;
if(!LOCPLINT->adventureInt->selection.selected)
{
if (LOCPLINT->adventureInt->heroList.items.size())
{
LOCPLINT->adventureInt->heroList.select(0);
}
}
draw((const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected);
}
if (!specific)
specific = (const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected;
//TODO: to rzutowanie wyglada groznie, ale dziala. Ale nie powinno wygladac groznie.
if(!specific)
return;
if(specific->ID == 34) //hero
{
if(LOCPLINT->heroWins.find(specific->subID)!=LOCPLINT->heroWins.end())
blitAt(LOCPLINT->heroWins[specific->subID],pos.x,pos.y);
}
//SDL_Surface * todr = LOCPLINT->infoWin(specific);
//if (!todr)
// return;
//blitAt(todr,pos.x,pos.y);
//SDL_FreeSurface(todr);
}
void CInfoBar::newDay(int Day)
{
mode = 1; //showing day
pom = 0;
TimeInterested::activate();
toNextTick = 500;
//blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
}
void CInfoBar::showComp(SComponent * comp, int time)
{
}
void CInfoBar::tick()
{
if (mode == 1) //new day animation
{
pom++;
if (pom >= day->ourImages.size())
{
TimeInterested::deactivate();
toNextTick = -1;
mode = 2;
draw();
return;
}
toNextTick = 250;
blitAt(day->ourImages[pom].bitmap,pos.x+10,pos.y+10);
std::stringstream txt;
txt << CGI->generaltexth->allTexts[64] << " " << LOCPLINT->cb->getDate(1);
printAtMiddle(txt.str(),700,420,TNRB16,zwykly);
if (pom == day->ourImages.size()-1)
toNextTick+=750;
}
}
CAdvMapInt::CAdvMapInt(int Player)
:player(Player),
statusbar(7,556),

View File

@@ -186,11 +186,19 @@ public:
void draw();
};
class CInfoBar
:public virtual CIntObject
:public virtual CIntObject, public TimeInterested
{
public:
CDefHandler *day, *week1, *week2, *week3, *week4;
int mode;
int pom;
CInfoBar();
void draw(void * specific=NULL); // if specific==0 function draws info about selected hero/town
~CInfoBar();
void newDay(int Day);
void showComp(SComponent * comp, int time=5000);
void tick();
void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
};
/*****************************/
class CAdvMapInt //adventure map interface
@@ -203,7 +211,6 @@ public:
int player;
std::vector<CDefHandler *> gems;
bool scrollingLeft ;
bool scrollingRight ;

View File

@@ -107,6 +107,73 @@ void SComponent::deactivate()
{
ClickableR::deactivate();
}
void CSelectableComponent::clickLeft(tribool down)
{
if (down)
{
select(true);
}
}
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, SDL_Surface * Border)
:SComponent(Type,Sub,Val)
{
if (Border) //use custom border
{
border = Border;
}
else //we need to draw border
{
SDL_Surface * symb = SComponent::getImg();
border = CSDL_Ext::newSurface(symb->w+2,symb->h+2,symb);
SDL_FillRect(border,NULL,0x00FFFF);
for (int i=0;i<border->w;i++)
{
SDL_PutPixel(border,i,0,239,215,123);
SDL_PutPixel(border,i,(border->h)-1,239,215,123);
}
for (int i=0;i<border->h;i++)
{
SDL_PutPixel(border,0,i,239,215,123);
SDL_PutPixel(border,(border->w)-1,i,239,215,123);
}
SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
}
selected = false;
}
void CSelectableComponent::activate()
{
SComponent::activate();
ClickableL::activate();
}
void CSelectableComponent::deactivate()
{
SComponent::deactivate();
ClickableL::deactivate();
}
SDL_Surface * CSelectableComponent::getImg()
{
return myBitmap;
}
void CSelectableComponent::select(bool on)
{
if(on != selected)
{
blitAt(SComponent::getImg(),1,1,myBitmap);
if (on)
{
blitAt(SComponent::getImg(),0,0,border);
}
selected = on;
return;
}
else
{
return;
}
}
void CSimpleWindow::show(SDL_Surface * to)
{
if(!to)
@@ -122,6 +189,28 @@ CSimpleWindow::~CSimpleWindow()
}
}
void CSelWindow::selectionChange(SComponent * to)
{
for (int i=0;i<components.size();i++)
{
if(components[i]==to)
continue;
CSelectableComponent * pom = dynamic_cast<CSelectableComponent*>(components[i]);
if (!pom)
continue;
pom->select(false);
}
}
void CSelWindow::okClicked(tribool down)
{
if(!down)
close();
}
void CSelWindow::close()
{
//call owner with selection result
CInfoWindow::close();
}
template <typename T>CSCButton<T>::CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(tribool), T* Delg)
{
ourObj = obj;
@@ -259,7 +348,15 @@ void MotionInterested::deactivate()
LOCPLINT->
motioninterested.erase(std::find(LOCPLINT->motioninterested.begin(),LOCPLINT->motioninterested.end(),this));
}
void TimeInterested::activate()
{
LOCPLINT->timeinterested.push_back(this);
}
void TimeInterested::deactivate()
{
LOCPLINT->
timeinterested.erase(std::find(LOCPLINT->timeinterested.begin(),LOCPLINT->timeinterested.end(),this));
}
CPlayerInterface::CPlayerInterface(int Player, int serial)
{
playerID=Player;
@@ -291,12 +388,20 @@ void CPlayerInterface::init(ICallback * CB)
cb = dynamic_cast<CCallback*>(CB);
CGI->localPlayer = serialID;
adventureInt = new CAdvMapInt(playerID);
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
for(int i=0;i<hh.size();i++)
{
SDL_Surface * pom = infoWin(hh[i]);
heroWins.insert(std::pair<int,SDL_Surface*>(hh[i]->subID,pom));
}
}
void CPlayerInterface::yourTurn()
{
makingTurn = true;
CGI->localPlayer = serialID;
unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
adventureInt->infoBar.newDay(cb->getDate(1));
adventureInt->show();
//show rest of things
@@ -306,17 +411,26 @@ void CPlayerInterface::yourTurn()
SDL_setFramerate(mainFPSmng, 24);
SDL_Event sEvent;
//framerate keeper initialized
timeHandler th;
th.getDif();
for(;makingTurn;) // main loop
{
CGI->screenh->updateScreen();
int tv = th.getDif();
for (int i=0;i<timeinterested.size();i++)
{
if (timeinterested[i]->toNextTick>=0)
timeinterested[i]->toNextTick-=tv;
if (timeinterested[i]->toNextTick<0)
timeinterested[i]->tick();
}
LOCPLINT->adventureInt->updateScreen = false;
while (SDL_PollEvent(&sEvent)) //wait for event...
{
handleEvent(&sEvent);
}
++LOCPLINT->adventureInt->animValHitCount; //for animations
if(LOCPLINT->adventureInt->animValHitCount == 2)
if(LOCPLINT->adventureInt->animValHitCount == 4)
{
LOCPLINT->adventureInt->animValHitCount = 0;
++animVal;
@@ -939,6 +1053,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
CSDL_Ext::update(ekran);
CGI->screenh->updateScreen();
LOCPLINT->adventureInt->anim++;
adventureInt->animValHitCount=0;
SDL_framerateDelay(mainFPSmng); //for animation purposes
} //for(int i=1; i<32; i+=4)
//main moving done
@@ -1009,46 +1124,69 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
adventureInt->minimap.draw();
adventureInt->heroList.updateMove(ho);
}
void CPlayerInterface::heroKilled(const CGHeroInstance*)
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
{
heroWins.erase(hero->ID);
}
void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
{
if(heroWins.find(hero->subID)==heroWins.end())
heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
}
SDL_Surface * CPlayerInterface::infoWin(const void * specific) //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
SDL_Surface * CPlayerInterface::drawHeroInfoWin(const CGHeroInstance * curh)
{
char * buf = new char[10];
SDL_Surface * ret = copySurface(hInfo);
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
blueToPlayersAdv(ret,playerID,1);
printAt(curh->name,75,15,GEOR13,zwykly,ret);
for (int i=0;i<PRIMARY_SKILLS;i++)
{
itoa(curh->primSkills[i],buf,10);
printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
}
for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
{
blitAt(CGI->creh->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
itoa((*i).second.second,buf,10);
printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
}
blitAt(curh->type->portraitLarge,11,12,ret);
itoa(curh->mana,buf,10);
printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
delete buf;
blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
//SDL_SaveBMP(ret,"inf1.bmp");
return ret;
}
SDL_Surface * CPlayerInterface::drawTownInfoWin(const CGTownInstance * curh)
{
return NULL;
}
SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
{
if (specific)
;//TODO: dorobic, ale w ogole to moze lepiej najpierw zastapic tego voida czym innym
{
switch (specific->ID)
{
case 34:
return drawHeroInfoWin(dynamic_cast<const CGHeroInstance*>(specific));
break;
default:
return NULL;
break;
}
}
else
{
if (adventureInt->selection.type == HEROI_TYPE)
{
char * buf = new char[10];
SDL_Surface * ret = copySurface(hInfo);
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
blueToPlayersAdv(ret,playerID,1);
const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection.selected;
printAt(curh->name,75,15,GEOR13,zwykly,ret);
for (int i=0;i<PRIMARY_SKILLS;i++)
{
itoa(curh->primSkills[i],buf,10);
printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
}
for (std::map<int,std::pair<CCreature*,int> >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++)
{
blitAt(CGI->creh->smallImgs[(*i).second.first->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
itoa((*i).second.second,buf,10);
printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret);
}
blitAt(curh->type->portraitLarge,11,12,ret);
itoa(curh->mana,buf,10);
printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
delete buf;
blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
//SDL_SaveBMP(ret,"inf1.bmp");
return ret;
return drawHeroInfoWin(curh);
}
else if (adventureInt->selection.type == TOWNI_TYPE)
{
@@ -1105,6 +1243,17 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
case (SDLK_u):
{
adventureInt->underground.clickLeft(true);
break;
}
case (SDLK_m):
{
adventureInt->moveHero.clickLeft(true);
break;
}
case (SDLK_e):
{
adventureInt->endTurn.clickLeft(true);
break;
}
}
} //keydown end
@@ -1135,6 +1284,17 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
case (SDLK_u):
{
adventureInt->underground.clickLeft(false);
break;
}
case (SDLK_m):
{
adventureInt->moveHero.clickLeft(false);
break;
}
case (SDLK_e):
{
adventureInt->endTurn.clickLeft(false);
break;
}
}
}//keyup end
@@ -1256,6 +1416,8 @@ int3 CPlayerInterface::repairScreenPos(int3 pos)
}
void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val)
{
SDL_FreeSurface(heroWins[hero->ID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
heroWins[hero->ID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki.
if (adventureInt->selection.selected == hero)
adventureInt->infoBar.draw();
return;

View File

@@ -97,7 +97,14 @@ public:
virtual void activate()=0;
virtual void deactivate()=0;
};
class TimeInterested: public virtual CIntObject
{
public:
int toNextTick;
virtual void tick()=0;
virtual void activate();
virtual void deactivate();
};
template <typename T> class CSCButton: public CButtonBase, public ClickableL //prosty guzik, ktory tylko zmienia obrazek
{
public:
@@ -117,12 +124,17 @@ class CInfoWindow : public CSimpleWindow //text + comp. + ok button
public:
CSCButton<CInfoWindow> okb;
std::vector<SComponent*> components;
void okClicked(tribool down);
void close();
virtual void okClicked(tribool down);
virtual void close();
CInfoWindow();
~CInfoWindow();
};
class CSelWindow : public CInfoWindow //component selection window
{
void selectionChange(SComponent * to);
void okClicked(tribool down);
void close();
};
class SComponent : public ClickableR
{
public:
@@ -138,11 +150,24 @@ public:
SComponent(Etype Type, int Subtype, int Val);
//SComponent(const & SComponent r);
SDL_Surface * getImg();
void clickRight (tribool down);
virtual SDL_Surface * getImg();
virtual void activate();
virtual void deactivate();
};
class CSelectableComponent : public SComponent, public ClickableL
{
public:
bool selected;
SDL_Surface * border, *myBitmap;
void clickLeft(tribool down);
CSelectableComponent(Etype Type, int Sub, int Val, SDL_Surface * Border=NULL);
void activate();
void deactivate();
void select(bool on);
SDL_Surface * getImg();
};
class CPlayerInterface : public CGameInterface
@@ -161,29 +186,34 @@ public:
std::vector<Hoverable*> hoverable;
std::vector<KeyInterested*> keyinterested;
std::vector<MotionInterested*> motioninterested;
std::vector<TimeInterested*> timeinterested;
std::vector<IShowable*> objsToBlit;
SDL_Surface * hInfo;
std::vector<std::pair<int, int> > slotsPos;
CDefEssential *luck22, *luck30, *luck42, *luck82,
*morale22, *morale30, *morale42, *morale82;
std::map<int,SDL_Surface*> heroWins;
//std::map<int,SDL_Surface*> townWins;
//overloaded funcs from Interface
void yourTurn();
void heroMoved(const HeroMoveDetails & details);
void tileRevealed(int3 pos);
void tileHidden(int3 pos);
void heroKilled(const CGHeroInstance*);
void heroCreated(const CGHeroInstance*);
void heroKilled(const CGHeroInstance* hero);
void heroCreated(const CGHeroInstance* hero);
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
void receivedResource(int type, int val);
SDL_Surface * infoWin(const void * specific); //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void*
void handleEvent(SDL_Event * sEvent);
void init(ICallback * CB);
int3 repairScreenPos(int3 pos);
void showInfoDialog(std::string text, std::vector<SComponent*> & components);
void removeObjToBlit(IShowable* obj);
SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
SDL_Surface * drawTownInfoWin(const CGTownInstance * curh);
CPlayerInterface(int Player, int serial);
};