1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Obtaining town instance pointer via cb. Plz, don't access gamestate directly from player interface! Everything has to go via callback.

Commented out giving starting artifact - new artifact randomization make it crashing. Please fix it.

New control - CTextBox - for multi-line text with optional slider. Used it for map description and info windows. Related changes. Fixes #22 and #96.
This commit is contained in:
Michał W. Urbańczyk 2010-07-06 02:10:26 +00:00
parent e4fcfd7044
commit d0ff61807d
22 changed files with 568 additions and 390 deletions

View File

@ -164,17 +164,15 @@ const CGTownInstance * CCallback::getTownInfo(int val, bool mode) const //mode =
else else
return NULL; return NULL;
} }
else else if(mode == 1)
{ {
//TODO: add some smart ID to the CTownInstance const CGObjectInstance *obj = getObjectInfo(val);
if(!obj)
//for (int i=0; i<gs->players[gs->currentPlayer].towns.size();i++)
//{
// if (gs->players[gs->currentPlayer].towns[i]->someID==val)
// return gs->players[gs->currentPlayer].towns[i];
//}
return NULL; return NULL;
if(obj->ID != TOWNI_TYPE)
return NULL;
else
return static_cast<const CGTownInstance *>(obj);
} }
return NULL; return NULL;
} }
@ -241,6 +239,7 @@ const CGHeroInstance * CCallback::getHeroInfo(int val, int mode) const //mode =
const CGObjectInstance * CCallback::getObjectInfo(int ID) const const CGObjectInstance * CCallback::getObjectInfo(int ID) const
{ {
//TODO: check for visibility
return gs->map->objects[ID]; return gs->map->objects[ID];
} }

View File

@ -141,7 +141,7 @@ public:
//town //town
virtual int howManyTowns()const =0; virtual int howManyTowns()const =0;
virtual const CGTownInstance * getTownInfo(int val, bool mode)const =0; //mode = 0 -> val = serial; mode = 1 -> val = ID virtual const CGTownInstance * getTownInfo(int val, bool mode)const =0; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
virtual std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const=0; virtual std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const=0;
virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
@ -245,7 +245,7 @@ public:
int getResourceAmount(int type) const; int getResourceAmount(int type) const;
std::vector<si32> getResourceAmount() const; std::vector<si32> getResourceAmount() const;
int howManyHeroes(bool includeGarrisoned = true) const; int howManyHeroes(bool includeGarrisoned = true) const;
const CGTownInstance * getTownInfo(int val, bool mode) const; //mode = 0 -> val = serial; mode = 1 -> val = ID const CGTownInstance * getTownInfo(int val, bool mode) const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const; std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const;
int howManyTowns()const; int howManyTowns()const;
std::vector < std::string > getObjDescriptions(int3 pos) const; //returns descriptions of objects at pos in order from the lowest to the highest std::vector < std::string > getObjDescriptions(int3 pos) const; //returns descriptions of objects at pos in order from the lowest to the highest

View File

@ -637,3 +637,46 @@ void CSlider::setAmount( int to )
positions = to - capacity; positions = to - capacity;
amax(positions, 0); amax(positions, 0);
} }
void CSlider::showAll(SDL_Surface * to)
{
SDL_FillRect(to, &pos, 0);
CIntObject::showAll(to);
}
void CSlider::wheelScrolled(bool down, bool in)
{
moveTo(value + 3 * (down ? +1 : -1));
}
void CSlider::keyPressed(const SDL_KeyboardEvent & key)
{
if(key.state != SDL_PRESSED) return;
int moveDest = 0;
switch(key.keysym.sym)
{
case SDLK_UP:
moveDest = value - 1;
break;
case SDLK_DOWN:
moveDest = value + 1;
break;
case SDLK_PAGEUP:
moveDest = value - capacity + 1;
break;
case SDLK_PAGEDOWN:
moveDest = value + capacity - 1;
break;
case SDLK_HOME:
moveDest = 0;
break;
case SDLK_END:
moveDest = amount - capacity;
break;
default:
return;
}
moveTo(moveDest);
}

View File

@ -125,25 +125,27 @@ public:
positions, //number of highest position (0 if there is only one) positions, //number of highest position (0 if there is only one)
value; //first active element value; //first active element
bool horizontal; bool horizontal;
bool wheelScrolling;
bool keyScrolling;
CDefEssential *imgs ; CDefEssential *imgs ;
boost::function<void(int)> moved; boost::function<void(int)> moved;
//void(T::*moved)(int to);
//T* owner;
void redrawSlider(); void redrawSlider();
void sliderClicked(); void sliderClicked();
void moveLeft(); void moveLeft();
void clickLeft(tribool down, bool previousState);
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void moveRight(); void moveRight();
void moveTo(int to); void moveTo(int to);
void block(bool on); void block(bool on);
void setAmount(int to); void setAmount(int to);
//void activate(); // makes button active
//void deactivate(); // makes button inactive (but doesn't delete) void keyPressed(const SDL_KeyboardEvent & key);
//void show(SDL_Surface * to); void wheelScrolled(bool down, bool in);
void clickLeft(tribool down, bool previousState);
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void showAll(SDL_Surface * to);
CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int Capacity, int Amount, CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int Capacity, int Amount,
int Value=0, bool Horizontal=true, int style = 0); //style 0 - brown, 1 - blue int Value=0, bool Horizontal=true, int style = 0); //style 0 - brown, 1 - blue
~CSlider(); ~CSlider();

View File

@ -778,7 +778,7 @@ void CCastleInterface::buildingClicked(int building)
void CCastleInterface::castleTeleport(int where) void CCastleInterface::castleTeleport(int where)
{ {
const CGTownInstance * dest = dynamic_cast<const CGTownInstance *>(CGI->state->map->objects[where]); const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(where, 1);
LOCPLINT->cb->teleportHero(town->visitingHero, dest); LOCPLINT->cb->teleportHero(town->visitingHero, dest);
close();//close this window, interface with new town will be called by town::onVisit close();//close this window, interface with new town will be called by town::onVisit
} }

View File

@ -418,29 +418,27 @@ void CHeroWindow::redrawCurBack()
CSDL_Ext::printAtMiddle(CGI->generaltexth->jktexts[4], 262, 99, FONT_SMALL, tytulowy, curBack); CSDL_Ext::printAtMiddle(CGI->generaltexth->jktexts[4], 262, 99, FONT_SMALL, tytulowy, curBack);
//dismiss / quest log //dismiss / quest log
std::vector<std::string> * toPrin = CMessage::breakText(CGI->generaltexth->jktexts[8].substr(1, CGI->generaltexth->jktexts[8].size()-2)); std::vector<std::string> toPrin = CMessage::breakText(CGI->generaltexth->jktexts[8].substr(1, CGI->generaltexth->jktexts[8].size()-2));
if(toPrin->size()==1) if(toPrin.size()==1)
{ {
CSDL_Ext::printAt((*toPrin)[0], 372, 439, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[0], 372, 439, FONT_SMALL, zwykly, curBack);
} }
else else
{ {
CSDL_Ext::printAt((*toPrin)[0], 372, 430, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[0], 372, 430, FONT_SMALL, zwykly, curBack);
CSDL_Ext::printAt((*toPrin)[1], 372, 446, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[1], 372, 446, FONT_SMALL, zwykly, curBack);
} }
delete toPrin;
toPrin = CMessage::breakText(CGI->generaltexth->jktexts[9].substr(1, CGI->generaltexth->jktexts[9].size()-2)); toPrin = CMessage::breakText(CGI->generaltexth->jktexts[9].substr(1, CGI->generaltexth->jktexts[9].size()-2));
if(toPrin->size()==1) if(toPrin.size()==1)
{ {
CSDL_Ext::printAt((*toPrin)[0], 512, 439, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[0], 512, 439, FONT_SMALL, zwykly, curBack);
} }
else else
{ {
CSDL_Ext::printAt((*toPrin)[0], 512, 430, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[0], 512, 430, FONT_SMALL, zwykly, curBack);
CSDL_Ext::printAt((*toPrin)[1], 512, 446, FONT_SMALL, zwykly, curBack); CSDL_Ext::printAt(toPrin[1], 512, 446, FONT_SMALL, zwykly, curBack);
} }
delete toPrin;
//printing primary skills' amounts //printing primary skills' amounts
for(int m=0; m<4; ++m) for(int m=0; m<4; ++m)

View File

@ -652,19 +652,17 @@ void CKingdomInterface::CTownItem::showAll(SDL_Surface * to)
oss << town->dailyIncome(); oss << town->dailyIncome();
CSDL_Ext::printAtMiddle(oss.str(),pos.x+189,pos.y+61,FONT_SMALL,zwykly,to); CSDL_Ext::printAtMiddle(oss.str(),pos.x+189,pos.y+61,FONT_SMALL,zwykly,to);
std::vector<std::string> * toPrin = CMessage::breakText(CGI->generaltexth->allTexts[265]); std::vector<std::string> toPrin = CMessage::breakText(CGI->generaltexth->allTexts[265]);
CSDL_Ext::printAt((*toPrin)[0], pos.x+4, pos.y+76, FONT_SMALL, tytulowy, to); CSDL_Ext::printAt(toPrin[0], pos.x+4, pos.y+76, FONT_SMALL, tytulowy, to);
if(toPrin->size()!=1) if(toPrin.size()!=1)
CSDL_Ext::printAt((*toPrin)[1], pos.x+4, pos.y+92, FONT_SMALL, tytulowy, to); CSDL_Ext::printAt(toPrin[1], pos.x+4, pos.y+92, FONT_SMALL, tytulowy, to);
delete toPrin;
toPrin = CMessage::breakText(CGI->generaltexth->allTexts[266]); toPrin = CMessage::breakText(CGI->generaltexth->allTexts[266]);
CSDL_Ext::printAt((*toPrin)[0], pos.x+351, pos.y+76, FONT_SMALL, tytulowy, to); CSDL_Ext::printAt(toPrin[0], pos.x+351, pos.y+76, FONT_SMALL, tytulowy, to);
if(toPrin->size()!=1) if(toPrin.size()!=1)
CSDL_Ext::printAt((*toPrin)[1], pos.x+351, pos.y+92, FONT_SMALL, tytulowy, to); CSDL_Ext::printAt(toPrin[1], pos.x+351, pos.y+92, FONT_SMALL, tytulowy, to);
delete toPrin;
for (int i=0; i<CREATURES_PER_TOWN;i++) for (int i=0; i<CREATURES_PER_TOWN;i++)
{//creatures info {//creatures info

View File

@ -113,33 +113,30 @@ SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor) //draws box for
/* The map file contains long texts, with or without line breaks. This /* The map file contains long texts, with or without line breaks. This
* method takes such a text and breaks it into into several lines. */ * method takes such a text and breaks it into into several lines. */
std::vector<std::string> * CMessage::breakText(std::string text, size_t maxLineSize, std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSize/*=30*/, const boost::function<int(char)> &charMetric /*= 0*/, bool allowLeadingWhitespace /*= false*/ )
bool userBreak, bool ifor)
{ {
std::vector<std::string> * ret = new std::vector<std::string>(); std::vector<std::string> ret;
boost::algorithm::trim_if(text,boost::algorithm::is_any_of(" ")); boost::algorithm::trim_right_if(text,boost::algorithm::is_any_of(" "));
while (text.length()) while (text.length())
{ {
unsigned int lineLength = 0; //in characters or given char metric
unsigned int z = 0; //our position in text
bool opened = false;//if we have an unclosed brace in current line
bool lineManuallyBroken = false;
unsigned int z = 0; while(z < text.length() && text[z] != 0x0a && lineLength < maxLineSize)
unsigned int braces = 0;
bool opened = false;
while(z < text.length() && (text[z] != 0x0a) && (z < maxLineSize+braces))
{ {
/* We don't count braces in string length. */ /* We don't count braces in string length. */
if (text[z] == '{') if (text[z] == '{')
{
opened=true; opened=true;
braces++;
}
else if (text[z]=='}') else if (text[z]=='}')
{
opened=false; opened=false;
braces++; else if(charMetric)
} lineLength += charMetric(text[z]);
else
lineLength++;
z++; z++;
} }
@ -152,10 +149,13 @@ std::vector<std::string> * CMessage::breakText(std::string text, size_t maxLineS
int pos = z-1; int pos = z-1;
// Do not break an ellipsis, backtrack until whitespace. // Do not break an ellipsis, backtrack until whitespace.
if (text[pos] == '.' && text[z] == '.') { if (text[pos] == '.' && text[z] == '.')
{
while (pos != 0 && text[pos] != ' ') while (pos != 0 && text[pos] != ' ')
pos--; pos--;
} else { }
else
{
/* TODO: boost should have a nice method to do that. */ /* TODO: boost should have a nice method to do that. */
while(pos > 0 && while(pos > 0 &&
text[pos] != ' ' && text[pos] != ' ' &&
@ -172,17 +172,17 @@ std::vector<std::string> * CMessage::breakText(std::string text, size_t maxLineS
if(z) //non-blank line if(z) //non-blank line
{ {
ret->push_back(text.substr(0, z)); ret.push_back(text.substr(0, z));
if (opened) if (opened)
/* Close the brace for the current line. */ /* Close the brace for the current line. */
ret->back() += '}'; ret.back() += '}';
text.erase(0, z); text.erase(0, z);
} }
else if(text[z] == 0x0a) //blank line else if(text[z] == 0x0a) //blank line
{ {
ret->push_back(""); //add empty string, no extra actions needed ret.push_back(""); //add empty string, no extra actions needed
} }
if (text.length() && text[0] == 0x0a) if (text.length() && text[0] == 0x0a)
@ -193,8 +193,11 @@ std::vector<std::string> * CMessage::breakText(std::string text, size_t maxLineS
/* Remove LF */ /* Remove LF */
text.erase(0, 1); text.erase(0, 1);
lineManuallyBroken = true;
} }
if(!allowLeadingWhitespace || !lineManuallyBroken)
boost::algorithm::trim_left_if(text,boost::algorithm::is_any_of(" ")); boost::algorithm::trim_left_if(text,boost::algorithm::is_any_of(" "));
if (opened) if (opened)
@ -206,12 +209,18 @@ std::vector<std::string> * CMessage::breakText(std::string text, size_t maxLineS
} }
/* Trim whitespaces of every line. */ /* Trim whitespaces of every line. */
for (size_t i=0; i<ret->size(); i++) if(!allowLeadingWhitespace)
boost::algorithm::trim((*ret)[i]); for (size_t i=0; i<ret.size(); i++)
boost::algorithm::trim(ret[i]);
return ret; return ret;
} }
std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWidth, EFonts font )
{
return breakText(text, maxLineWidth, boost::bind(&Font::getCharWidth, graphics->fonts[font], _1), true);
}
std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight) std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight)
{ {
std::pair<int,int> ret; std::pair<int,int> ret;
@ -328,13 +337,14 @@ CSimpleWindow * CMessage::genWindow(std::string text, int player, bool centerOnM
{ {
CSimpleWindow * ret = new CSimpleWindow(); CSimpleWindow * ret = new CSimpleWindow();
int fontHeight; int fontHeight;
std::vector<std::string> * brtext = breakText(text,32,true,true); std::vector<std::string> brtext = breakText(text,32);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(brtext, fontHeight); std::vector<std::vector<SDL_Surface*> > * txtg = drawText(&brtext, fontHeight);
std::pair<int,int> txts = getMaxSizes(txtg, fontHeight); std::pair<int,int> txts = getMaxSizes(txtg, fontHeight);
ret->bitmap = drawBox1(txts.first+Lmar+Rmar,txts.second+Tmar+Bmar,player); ret->bitmap = drawBox1(txts.first+Lmar+Rmar,txts.second+Tmar+Bmar,player);
ret->pos.h = ret->bitmap->h; ret->pos.h = ret->bitmap->h;
ret->pos.w = ret->bitmap->w; ret->pos.w = ret->bitmap->w;
if (centerOnMouse) { if (centerOnMouse)
{
ret->pos.x = GH.current->motion.x - ret->pos.w/2; ret->pos.x = GH.current->motion.x - ret->pos.w/2;
ret->pos.y = GH.current->motion.y - ret->pos.h/2; ret->pos.y = GH.current->motion.y - ret->pos.h/2;
// Put the window back on screen if necessary // Put the window back on screen if necessary
@ -342,14 +352,15 @@ CSimpleWindow * CMessage::genWindow(std::string text, int player, bool centerOnM
amax(ret->pos.y, 0); amax(ret->pos.y, 0);
amin(ret->pos.x, conf.cc.resx - ret->pos.w); amin(ret->pos.x, conf.cc.resx - ret->pos.w);
amin(ret->pos.y, conf.cc.resy - ret->pos.h); amin(ret->pos.y, conf.cc.resy - ret->pos.h);
} else { }
else
{
// Center on screen // Center on screen
ret->pos.x = screen->w/2 - (ret->pos.w/2); ret->pos.x = screen->w/2 - (ret->pos.w/2);
ret->pos.y = screen->h/2 - (ret->pos.h/2); ret->pos.y = screen->h/2 - (ret->pos.h/2);
} }
int curh = ret->bitmap->h/2 - (fontHeight*txtg->size())/2; int curh = ret->bitmap->h/2 - (fontHeight*txtg->size())/2;
blitTextOnSur(txtg,fontHeight,curh,ret->bitmap); blitTextOnSur(txtg,fontHeight,curh,ret->bitmap);
delete brtext;
delete txtg; delete txtg;
return ret; return ret;
} }
@ -357,8 +368,8 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
{ {
int curh; int curh;
int fontHeight; int fontHeight;
std::vector<std::string> * tekst = breakText(text,charperline); std::vector<std::string> tekst = breakText(text,charperline);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst, fontHeight); std::vector<std::vector<SDL_Surface*> > * txtg = drawText(&tekst, fontHeight);
std::pair<int,int> txts = getMaxSizes(txtg, fontHeight), boxs; std::pair<int,int> txts = getMaxSizes(txtg, fontHeight), boxs;
boxs.first = std::max(txts.first,bitmap->w) // text/bitmap max width boxs.first = std::max(txts.first,bitmap->w) // text/bitmap max width
+ 50; //side margins + 50; //side margins
@ -376,7 +387,6 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret); blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret);
curh += bitmap->h + 5; curh += bitmap->h + 5;
CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+10,FONT_SMALL,zwykly,ret); CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+10,FONT_SMALL,zwykly,ret);
delete tekst;
delete txtg; delete txtg;
return ret; return ret;
} }
@ -384,32 +394,31 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline) void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline)
{ {
SDL_Surface * _or = NULL; SDL_Surface * _or = NULL;
int fontHeight; const Font &f = *graphics->fonts[FONT_MEDIUM];
int fontHeight = f.height;
// Try to compute a reasonable number of characters per line
if (!charperline)
{
if (text.size() < 30 && ret->buttons.size() < 2)
charperline = 30;
else if (text.size() < 200)
charperline = 40;
else if (text.size() < 750)
charperline = 50;
else
charperline = 75; //TODO: add scrollbar for very long texts
}
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = FNT_RenderText(FONT_MEDIUM,CGI->generaltexth->allTexts[4],zwykly); _or = FNT_RenderText(FONT_MEDIUM,CGI->generaltexth->allTexts[4],zwykly);
std::vector<std::string> * brtext = breakText(text, charperline, true, true); //text const int sizes[][2] = {{400, 100}, {500, 150}, {600, 200}};
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(brtext, fontHeight); for(int i = 0;
std::pair<int,int> txts = getMaxSizes(txtg, fontHeight); i < ARRAY_COUNT(sizes)
&& sizes[i][0] < conf.cc.resx - 150
&& sizes[i][1] < conf.cc.resy - 150
&& ret->text->slider;
i++)
{
ret->text->setBounds(sizes[i][0], sizes[i][1]);
}
if(ret->text->slider)
ret->text->slider->changeUsedEvents(CIntObject::WHEEL | CIntObject::KEYBOARD, true);
std::pair<int,int> winSize(ret->text->pos.w, ret->text->pos.h); //start with text size
ComponentsToBlit comps(ret->components,500,_or); ComponentsToBlit comps(ret->components,500,_or);
if (ret->components.size()) if (ret->components.size())
txts.second += 30 + comps.h; //space to first component winSize.second += 30 + comps.h; //space to first component
int bw = 0; int bw = 0;
if (ret->buttons.size()) if (ret->buttons.size())
@ -418,35 +427,32 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int
bw = 20*(ret->buttons.size()-1); // space between all buttons bw = 20*(ret->buttons.size()-1); // space between all buttons
for(size_t i=0; i<ret->buttons.size(); i++) //and add buttons width for(size_t i=0; i<ret->buttons.size(); i++) //and add buttons width
bw+=ret->buttons[i]->imgs[0][0]->w; bw+=ret->buttons[i]->imgs[0][0]->w;
txts.second += 20 + //before button winSize.second += 20 + //before button
ok->ourImages[0].bitmap->h; //button ok->ourImages[0].bitmap->h; //button
} }
// Clip window size // Clip window size
amax(txts.second, 50); amax(winSize.second, 50);
amax(txts.first, 80); amax(winSize.first, 80);
amax(txts.first, comps.w); amax(winSize.first, comps.w);
amax(txts.first, bw); amax(winSize.first, bw);
amin(txts.first, conf.cc.resx - 150); amin(winSize.first, conf.cc.resx - 150);
ret->bitmap = drawBox1 (txts.first + 2*SIDE_MARGIN, txts.second + 2*SIDE_MARGIN, player); ret->bitmap = drawBox1 (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player);
ret->pos.h=ret->bitmap->h; ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w; ret->pos.w=ret->bitmap->w;
ret->pos.x=screen->w/2-(ret->pos.w/2); ret->center();
ret->pos.y=screen->h/2-(ret->pos.h/2);
if (txts.second > conf.cc.resy - 150)
{
amin(txts.second, conf.cc.resy - 150);
ret->slider = new CSlider(ret->pos.x + ret->pos.w - SIDE_MARGIN, ret->pos.y + SIDE_MARGIN,
ret->pos.h - 2*SIDE_MARGIN, boost::bind (&CInfoWindow::sliderMoved, ret, _1), brtext->size(), brtext->size(), brtext->size()-1, false, 0);
//ret->bitmap->w -= ret->slider->pos.w; //crop text so that slider has more place for itself
}
else
ret->slider = NULL;
int curh = SIDE_MARGIN; int curh = SIDE_MARGIN;
blitTextOnSur (txtg, fontHeight, curh, ret->bitmap);
int xOffset = (ret->pos.w - ret->text->pos.w)/2;
ret->text->moveBy(Point(xOffset, SIDE_MARGIN));
//blitTextOnSur (txtg, fontHeight, curh, ret->bitmap);
curh += ret->text->pos.h;
if (ret->components.size()) if (ret->components.size())
{ {
@ -471,76 +477,11 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int
ret->components[i]->pos.x += ret->pos.x; ret->components[i]->pos.x += ret->pos.x;
ret->components[i]->pos.y += ret->pos.y; ret->components[i]->pos.y += ret->pos.y;
} }
delete brtext;
delete txtg;
if(_or) if(_or)
SDL_FreeSurface(_or); SDL_FreeSurface(_or);
} }
SDL_Surface * CMessage::genMessage
(std::string title, std::string text, EWindowType type, std::vector<CDefHandler*> *addPics, void * cb)
{
//max x 320 okolo 30 znakow
std::vector<std::string> * tekst;
if (text.length() < 30) //does not need breaking
{
tekst = new std::vector<std::string>();
tekst->push_back(text);
}
else tekst = breakText(text);
int ww, hh; //dimensions of box
if (319>30+13*text.length())
ww = 30+13*text.length();
else ww = 319;
if (title.length())
hh=110+(21*tekst->size());
else hh=60+(21*tekst->size());
if (type==yesOrNO) //make place for buttons
{
if (ww<200) ww=200;
hh+=70;
}
SDL_Surface * ret = drawBox1(ww,hh,0);
//prepare title text
if (title.length())
{
SDL_Surface * titleText = FNT_RenderText(FONT_BIG,title,tytulowy);
//draw title
SDL_Rect tytul = genRect(titleText->h,titleText->w,((ret->w/2)-(titleText->w/2)),37);
SDL_BlitSurface(titleText,NULL,ret,&tytul);
SDL_FreeSurface(titleText);
}
//draw text
for (size_t i=0; i<tekst->size(); i++)
{
int by = 37+i*21;
if (title.length()) by+=40;
SDL_Surface * tresc = FNT_RenderText(FONT_BIG,(*tekst)[i],zwykly);
SDL_Rect trescRect = genRect(tresc->h,tresc->w,((ret->w/2)-(tresc->w/2)),by);
SDL_BlitSurface(tresc,NULL,ret,&trescRect);
SDL_FreeSurface(tresc);
}
if (type==yesOrNO) // add buttons
{
int by = 77+tekst->size()*21;
if (title.length()) by+=40;
int hwo = (*addPics)[0]->ourImages[0].bitmap->w, hwc=(*addPics)[0]->ourImages[0].bitmap->w;
//ok
SDL_Rect trescRect = genRect((*addPics)[0]->ourImages[0].bitmap->h,hwo,((ret->w/2)-hwo-10),by);
SDL_BlitSurface((*addPics)[0]->ourImages[0].bitmap,NULL,ret,&trescRect);
reinterpret_cast<std::vector<SDL_Rect>*>(cb)->push_back(trescRect);
//cancel
trescRect = genRect((*addPics)[1]->ourImages[0].bitmap->h,hwc,((ret->w/2)+10),by);
SDL_BlitSurface((*addPics)[1]->ourImages[0].bitmap,NULL,ret,&trescRect);
reinterpret_cast<std::vector<SDL_Rect>*>(cb)->push_back(trescRect);
}
delete tekst;
return ret;
}
void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x, int y) void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x, int y)
{ {
//obwodka I-szego rzedu pozioma //border of 1st series, horizontal //obwodka I-szego rzedu pozioma //border of 1st series, horizontal
@ -582,9 +523,8 @@ ComponentResolved::ComponentResolved( SComponent *Comp )
{ {
comp = Comp; comp = Comp;
img = comp->getImg(); img = comp->getImg();
std::vector<std::string> * brtext = CMessage::breakText(comp->subtitle,13,true,true); //text std::vector<std::string> brtext = CMessage::breakText(comp->subtitle,13); //text
txt = CMessage::drawText(brtext,txtFontHeight,FONT_MEDIUM); txt = CMessage::drawText(&brtext,txtFontHeight,FONT_MEDIUM);
delete brtext;
//calculate dimensions //calculate dimensions
std::pair<int,int> textSize = CMessage::getMaxSizes(txt, txtFontHeight); std::pair<int,int> textSize = CMessage::getMaxSizes(txt, txtFontHeight);

View File

@ -4,6 +4,7 @@
#include "FontBase.h" #include "FontBase.h"
#include "../global.h" #include "../global.h"
#include <SDL.h> #include <SDL.h>
#include <boost/function.hpp>
/* /*
* CMessage.h, part of VCMI engine * CMessage.h, part of VCMI engine
@ -63,12 +64,11 @@ public:
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2 static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2
static void drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline); static void drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline);
static CSimpleWindow * genWindow(std::string text, int player, bool centerOnMouse=false, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins static CSimpleWindow * genWindow(std::string text, int player, bool centerOnMouse=false, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins
static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly,
std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL);
static SDL_Surface * drawBox1(int w, int h, int playerColor=1); static SDL_Surface * drawBox1(int w, int h, int playerColor=1);
static void drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0); static void drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55); static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55);
static std::vector<std::string> * breakText(std::string text, size_t maxLineSize=30, bool userBreak=true, bool ifor=true); static std::vector<std::string> breakText(std::string text, size_t maxLineSize=30, const boost::function<int(char)> &charMetric = boost::function<int(char)>(), bool allowLeadingWhitespace = false);
static std::vector<std::string> breakText(std::string text, size_t maxLineWidth, EFonts font);
static void init(); static void init();
static void dispose(); static void dispose();
}; };

View File

@ -828,6 +828,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
} }
slider = new CSlider(372, 86, tabType != CMenuScreen::saveGame ? 480 : 430, bind(&SelectionTab::sliderMove, this, _1), positions, curItems.size(), 0, false, 1); slider = new CSlider(372, 86, tabType != CMenuScreen::saveGame ? 480 : 430, bind(&SelectionTab::sliderMove, this, _1), positions, curItems.size(), 0, false, 1);
slider->changeUsedEvents(WHEEL, true);
format = CDefHandler::giveDef("SCSELC.DEF"); format = CDefHandler::giveDef("SCSELC.DEF");
sortingBy = _format; sortingBy = _format;
@ -1082,13 +1083,6 @@ void SelectionTab::clickLeft( tribool down, bool previousState )
select(line); select(line);
} }
} }
void SelectionTab::wheelScrolled( bool down, bool in )
{
slider->moveTo(slider->value + 3 * (down ? +1 : -1));
//select(selectionPos - slider->value + (down ? +1 : -1));
}
void SelectionTab::keyPressed( const SDL_KeyboardEvent & key ) void SelectionTab::keyPressed( const SDL_KeyboardEvent & key )
{ {
if(key.state != SDL_PRESSED) return; if(key.state != SDL_PRESSED) return;
@ -1166,23 +1160,25 @@ InfoCard::InfoCard( CMenuScreen::EState Type )
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
pos.x += 393; pos.x += 393;
used = RCLICK; used = RCLICK;
mapDescription = NULL;
type = Type; type = Type;
Rect descriptionRect(26, 149, 320, 115);
mapDescription = new CTextBox("", descriptionRect, 1);
if(type == CMenuScreen::campaignList) if(type == CMenuScreen::campaignList)
{ {
/*bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true); CSelectionScreen *ss = static_cast<CSelectionScreen*>(parent);
bg->pos.x = 0; moveChild(new CPicture(*ss->bg, descriptionRect + Point(-393, 0)), this, mapDescription, true); //move subpicture bg to our description control (by default it's our (Infocard) child)
bg->pos.y = 0;*/
} }
else else
{ {
bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true); bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true);
std::swap(children.front(), children.back());
pos.w = bg->pos.w; pos.w = bg->pos.w;
pos.h = bg->pos.h; pos.h = bg->pos.h;
sizes = CDefHandler::giveDef("SCNRMPSZ.DEF"); sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF"); sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
difficulty = new CHighlightableButtonsGroup(0); difficulty = new CHighlightableButtonsGroup(0);
{ {
static const char *difButns[] = {"GSPBUT3.DEF", "GSPBUT4.DEF", "GSPBUT5.DEF", "GSPBUT6.DEF", "GSPBUT7.DEF"}; static const char *difButns[] = {"GSPBUT3.DEF", "GSPBUT4.DEF", "GSPBUT5.DEF", "GSPBUT6.DEF", "GSPBUT7.DEF"};
@ -1197,6 +1193,9 @@ InfoCard::InfoCard( CMenuScreen::EState Type )
if(type != CMenuScreen::newGame) if(type != CMenuScreen::newGame)
difficulty->block(true); difficulty->block(true);
//description needs bg
moveChild(new CPicture(*bg, descriptionRect), this, mapDescription, true); //move subpicture bg to our description control (by default it's our (Infocard) child)
} }
} }
@ -1329,22 +1328,16 @@ void InfoCard::showAll( SDL_Surface * to )
} }
//blit description //blit description
std::string itemDesc, name; std::string name;
if (type == CMenuScreen::campaignList) if (type == CMenuScreen::campaignList)
{ {
itemDesc = curMap->campaignHeader->description;
name = curMap->campaignHeader->name; name = curMap->campaignHeader->name;
} }
else else
{ {
itemDesc = curMap->mapHeader->description;
name = curMap->mapHeader->name; name = curMap->mapHeader->name;
} }
std::vector<std::string> *desc = CMessage::breakText(itemDesc,52);
for (int i=0;i<desc->size();i++)
printAtLoc((*desc)[i], 26, 149 + i*16, FONT_SMALL, zwykly, to);
delete desc;
//name //name
if (name.length()) if (name.length())
@ -1358,8 +1351,17 @@ void InfoCard::showAll( SDL_Surface * to )
void InfoCard::changeSelection( const CMapInfo *to ) void InfoCard::changeSelection( const CMapInfo *to )
{ {
if(to && type != CMenuScreen::newGame && type != CMenuScreen::campaignList) if(to && mapDescription)
{
if (type == CMenuScreen::campaignList)
mapDescription->setTxt(to->campaignHeader->description);
else
mapDescription->setTxt(to->mapHeader->description);
if(type != CMenuScreen::newGame && type != CMenuScreen::campaignList)
difficulty->select(curOpts->difficulty, 0); difficulty->select(curOpts->difficulty, 0);
}
GH.totalRedraw(); GH.totalRedraw();
} }
@ -2220,10 +2222,10 @@ CBonusSelection::CBonusSelection( const CCampaign * _ourCampaign, int _whichMap
//campaign description //campaign description
printAtLoc(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, tytulowy, background); printAtLoc(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, tytulowy, background);
std::vector<std::string> *desc = CMessage::breakText(ourCampaign->header.description, 45); // std::vector<std::string> *desc = CMessage::breakText(ourCampaign->header.description, 45);
for (int i=0; i<desc->size() ;i++) // for (int i=0; i<desc->size() ;i++)
printAtLoc((*desc)[i], 481, 86 + i*16, FONT_SMALL, zwykly, background); // printAtLoc((*desc)[i], 481, 86 + i*16, FONT_SMALL, zwykly, background);
delete desc; // delete desc;
//set left part of window //set left part of window
for (int g=0; g<ourCampaign->scenarios.size(); ++g) for (int g=0; g<ourCampaign->scenarios.size(); ++g)
@ -2354,10 +2356,10 @@ void CBonusSelection::show( SDL_Surface * to )
//map description //map description
printAtLoc(CGI->generaltexth->allTexts[496], 481, 253, FONT_SMALL, tytulowy, to); printAtLoc(CGI->generaltexth->allTexts[496], 481, 253, FONT_SMALL, tytulowy, to);
std::vector<std::string> *desc = CMessage::breakText(mapDesc, 45); // std::vector<std::string> *desc = CMessage::breakText(mapDesc, 45);
for (int i=0; i<desc->size(); i++) // for (int i=0; i<desc->size(); i++)
printAtLoc((*desc)[i], 481, 281 + i*16, FONT_SMALL, zwykly, to); // printAtLoc((*desc)[i], 481, 281 + i*16, FONT_SMALL, zwykly, to);
delete desc; // delete desc;
//map size icon //map size icon
int temp; int temp;

View File

@ -23,6 +23,7 @@ class CCampaignHeader;
class CTextInput; class CTextInput;
class CCampaign; class CCampaign;
class CGStatusBar; class CGStatusBar;
class CTextBox;
class CMapInfo class CMapInfo
{ {
@ -86,6 +87,7 @@ class InfoCard : public CIntObject
public: public:
CMenuScreen::EState type; CMenuScreen::EState type;
CTextBox *mapDescription;
CHighlightableButtonsGroup *difficulty; CHighlightableButtonsGroup *difficulty;
CDefHandler *sizes, *sFlags;; CDefHandler *sizes, *sFlags;;
@ -135,7 +137,6 @@ public:
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
void clickLeft(tribool down, bool previousState); void clickLeft(tribool down, bool previousState);
void wheelScrolled(bool down, bool in);
void keyPressed(const SDL_KeyboardEvent & key); void keyPressed(const SDL_KeyboardEvent & key);
void onDoubleClick(); void onDoubleClick();
SelectionTab(CMenuScreen::EState Type, const boost::function<void(CMapInfo *)> &OnSelect, bool MultiPlayer=false); SelectionTab(CMenuScreen::EState Type, const boost::function<void(CMapInfo *)> &OnSelect, bool MultiPlayer=false);
@ -201,10 +202,10 @@ public:
class CSelectionScreen : public CIntObject class CSelectionScreen : public CIntObject
{ {
public:
CPicture *bg; //general bg image CPicture *bg; //general bg image
InfoCard *card; InfoCard *card;
OptionsTab *opt; OptionsTab *opt;
public:
AdventureMapButton *start, *back; AdventureMapButton *start, *back;
SelectionTab *sel; SelectionTab *sel;

View File

@ -16,4 +16,24 @@ enum EFonts
FONT_BIG, FONT_CALLI, FONT_CREDITS, FONT_HIGH_SCORE, FONT_MEDIUM, FONT_SMALL, FONT_TIMES, FONT_TINY, FONT_VERD FONT_BIG, FONT_CALLI, FONT_CREDITS, FONT_HIGH_SCORE, FONT_MEDIUM, FONT_SMALL, FONT_TIMES, FONT_TINY, FONT_VERD
}; };
struct Font
{
struct Char
{
si32 unknown1, width, unknown2, offset;
unsigned char *pixels;
};
Char chars[256];
ui8 height;
unsigned char *data;
Font(unsigned char *Data);
~Font();
int getWidth(const char *text) const;
int getCharWidth(char c) const;
};
#endif #endif

View File

@ -522,22 +522,7 @@ void CIntObject::activate()
{ {
assert(!active); assert(!active);
active |= GENERAL; active |= GENERAL;
if(used & LCLICK) activate(used);
activateLClick();
if(used & RCLICK)
activateRClick();
if(used & HOVER)
activateHover();
if(used & MOVE)
activateMouseMove();
if(used & KEYBOARD)
activateKeys();
if(used & TIME)
activateTimer();
if(used & WHEEL)
activateWheel();
if(used & DOUBLECLICK)
activateDClick();
if(defActions & ACTIVATE) if(defActions & ACTIVATE)
for(size_t i = 0; i < children.size(); i++) for(size_t i = 0; i < children.size(); i++)
@ -545,26 +530,31 @@ void CIntObject::activate()
children[i]->activate(); children[i]->activate();
} }
void CIntObject::activate(ui16 what)
{
if(what & LCLICK)
activateLClick();
if(what & RCLICK)
activateRClick();
if(what & HOVER)
activateHover();
if(what & MOVE)
activateMouseMove();
if(what & KEYBOARD)
activateKeys();
if(what & TIME)
activateTimer();
if(what & WHEEL)
activateWheel();
if(what & DOUBLECLICK)
activateDClick();
}
void CIntObject::deactivate() void CIntObject::deactivate()
{ {
assert(active); assert(active);
active &= ~ GENERAL; active &= ~ GENERAL;
if(used & LCLICK) deactivate(used);
deactivateLClick();
if(used & RCLICK)
deactivateRClick();
if(used & HOVER)
deactivateHover();
if(used & MOVE)
deactivateMouseMove();
if(used & KEYBOARD)
deactivateKeys();
if(active & TIME) // TIME is special
deactivateTimer();
if(used & WHEEL)
deactivateWheel();
if(used & DOUBLECLICK)
deactivateDClick();
assert(!active); assert(!active);
@ -574,6 +564,26 @@ void CIntObject::deactivate()
children[i]->deactivate(); children[i]->deactivate();
} }
void CIntObject::deactivate(ui16 what)
{
if(what & LCLICK)
deactivateLClick();
if(what & RCLICK)
deactivateRClick();
if(what & HOVER)
deactivateHover();
if(what & MOVE)
deactivateMouseMove();
if(what & KEYBOARD)
deactivateKeys();
if(what & TIME) // TIME is special
deactivateTimer();
if(what & WHEEL)
deactivateWheel();
if(what & DOUBLECLICK)
deactivateDClick();
}
CIntObject::~CIntObject() CIntObject::~CIntObject()
{ {
assert(!active); //do not delete active obj assert(!active); //do not delete active obj
@ -684,18 +694,19 @@ void CIntObject::onDoubleClick()
{ {
} }
const Rect & CIntObject::center( const Rect &r ) const Rect & CIntObject::center( const Rect &r, bool propagate )
{ {
pos.w = r.w; pos.w = r.w;
pos.h = r.h; pos.h = r.h;
pos.x = screen->w/2 - r.w/2; moveBy(Point(screen->w/2 - r.w/2 - pos.x,
pos.y = screen->h/2 - r.h/2; screen->h/2 - r.h/2 - pos.y),
propagate);
return pos; return pos;
} }
const Rect & CIntObject::center() const Rect & CIntObject::center( bool propagate )
{ {
return center(pos); return center(pos, propagate);
} }
void CIntObject::moveBy( const Point &p, bool propagate /*= true*/ ) void CIntObject::moveBy( const Point &p, bool propagate /*= true*/ )
@ -718,8 +729,45 @@ void CIntObject::delChild(CIntObject *child)
delete child; delete child;
} }
void CIntObject::addChild(CIntObject *child, bool adjustPosition /*= false*/)
{
assert(!vstd::contains(children, child));
assert(child->parent == NULL);
children.push_back(child);
child->parent = this;
if(adjustPosition)
child->pos += pos;
}
void CIntObject::removeChild(CIntObject *child, bool adjustPosition /*= false*/)
{
assert(vstd::contains(children, child));
assert(child->parent == this);
children -= child;
child->parent = NULL;
if(adjustPosition)
child->pos -= pos;
}
void CIntObject::changeUsedEvents(ui16 what, bool enable, bool adjust /*= true*/)
{
if(enable)
{
used |= what;
if(adjust && active)
activate(what);
}
else
{
used &= ~what;
if(adjust && active)
deactivate(what);
}
}
CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free ) CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
{ {
init();
bg = BG; bg = BG;
freeSurf = Free; freeSurf = Free;
pos.x += x; pos.x += x;
@ -730,6 +778,7 @@ CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
CPicture::CPicture( const std::string &bmpname, int x, int y ) CPicture::CPicture( const std::string &bmpname, int x, int y )
{ {
init();
bg = BitmapHandler::loadBitmap(bmpname); bg = BitmapHandler::loadBitmap(bmpname);
freeSurf = true;; freeSurf = true;;
pos.x += x; pos.x += x;
@ -747,25 +796,54 @@ CPicture::CPicture( const std::string &bmpname, int x, int y )
CPicture::CPicture(const Rect &r, const SDL_Color &color, bool screenFormat /*= false*/) CPicture::CPicture(const Rect &r, const SDL_Color &color, bool screenFormat /*= false*/)
{ {
init();
createSimpleRect(r, screenFormat, SDL_MapRGB(bg->format, color.r, color.g,color.b)); createSimpleRect(r, screenFormat, SDL_MapRGB(bg->format, color.r, color.g,color.b));
} }
CPicture::CPicture(const Rect &r, ui32 color, bool screenFormat /*= false*/) CPicture::CPicture(const Rect &r, ui32 color, bool screenFormat /*= false*/)
{ {
init();
createSimpleRect(r, screenFormat, color); createSimpleRect(r, screenFormat, color);
} }
CPicture::CPicture(SDL_Surface *BG, const Rect &SrcRect, int x /*= 0*/, int y /*= 0*/, bool free /*= false*/)
{
srcRect = new Rect(SrcRect);
pos.x += x;
pos.y += y;
bg = BG;
freeSurf = free;
}
CPicture::~CPicture() CPicture::~CPicture()
{ {
if(freeSurf) if(freeSurf)
SDL_FreeSurface(bg); SDL_FreeSurface(bg);
delete srcRect;
}
void CPicture::init()
{
srcRect = NULL;
} }
void CPicture::showAll( SDL_Surface * to ) void CPicture::showAll( SDL_Surface * to )
{ {
if(bg) if(bg)
{
if(srcRect)
{
SDL_Rect srcRectCpy = *srcRect;
SDL_Rect dstRect = srcRectCpy;
dstRect.x = pos.x;
dstRect.y = pos.y;
SDL_BlitSurface(bg, &srcRectCpy, to, &dstRect);
}
else
blitAt(bg, pos, to); blitAt(bg, pos, to);
} }
}
void CPicture::convertToScreenBPP() void CPicture::convertToScreenBPP()
{ {
@ -786,6 +864,7 @@ void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
bg = SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 8, 0, 0, 0, 0); bg = SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 8, 0, 0, 0, 0);
SDL_FillRect(bg, NULL, color); SDL_FillRect(bg, NULL, color);
freeSurf = true;
} }
void CPicture::colorizeAndConvert(int player) void CPicture::colorizeAndConvert(int player)
@ -868,16 +947,10 @@ bool isArrowKey( SDLKey key )
return key >= SDLK_UP && key <= SDLK_LEFT; return key >= SDLK_UP && key <= SDLK_LEFT;
} }
CIntObject * moveChildren(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos) CIntObject * moveChild(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos)
{ {
assert(vstd::contains(from->children, obj)); from->removeChild(obj, adjustPos);
assert(obj->parent == from); to->addChild(obj, adjustPos);
from->children -= obj;
to->children.push_back(obj);
obj->parent = to;
if(adjustPos)
obj->pos -= from->pos - to->pos;
return obj; return obj;
} }
Rect Rect::createCentered( int w, int h ) Rect Rect::createCentered( int w, int h )

View File

@ -213,7 +213,7 @@ struct Rect : public SDL_Rect
} }
template<typename T> Rect operator-(const T &t) template<typename T> Rect operator-(const T &t)
{ {
return Rect(x + t.x, y + t.y, w, h); return Rect(x - t.x, y - t.y, w, h);
} }
Rect operator&(const Rect &p) const //rect intersection Rect operator&(const Rect &p) const //rect intersection
{ {
@ -376,6 +376,8 @@ public:
void defDeactivate(); void defDeactivate();
void activate(); void activate();
void deactivate(); void deactivate();
void activate(ui16 what);
void deactivate(ui16 what);
void show(SDL_Surface * to); void show(SDL_Surface * to);
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
@ -388,12 +390,26 @@ public:
void blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst); void blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst);
bool isItInLoc(const SDL_Rect &rect, int x, int y); bool isItInLoc(const SDL_Rect &rect, int x, int y);
bool isItInLoc(const SDL_Rect &rect, const Point &p); bool isItInLoc(const SDL_Rect &rect, const Point &p);
const Rect & center(const Rect &r); //sets pos so that r will be in the center of screen, returns new position const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, returns new position
const Rect & center(); //centers when pos.w and pos.h are set, returns new position const Rect & center(bool propagate = true); //centers when pos.w and pos.h are set, returns new position
void moveBy(const Point &p, bool propagate = true); void moveBy(const Point &p, bool propagate = true);
void moveTo(const Point &p, bool propagate = true); void moveTo(const Point &p, bool propagate = true);
void changeUsedEvents(ui16 what, bool enable, bool adjust = true);
void delChild(CIntObject *child); //removes from chidlren list, deletes void addChild(CIntObject *child, bool adjustPosition = false);
void removeChild(CIntObject *child, bool adjustPosition = false);
void delChild(CIntObject *child); //removes from children list, deletes
template <typename T> void delChildNUll(T *&child, bool deactivateIfNeeded = false) //removes from children list, deletes and sets pointer to NULL
{
if(!child)
return;
if(deactivateIfNeeded && child->active)
child->deactivate();
delChild(child);
child = NULL;
}
}; };
//class for binding keys to left mouse button clicks //class for binding keys to left mouse button clicks
@ -419,29 +435,29 @@ class CSimpleWindow : public CIntObject
{ {
public: public:
SDL_Surface * bitmap; //background SDL_Surface * bitmap; //background
CIntObject * owner; //who made this window
virtual void show(SDL_Surface * to); virtual void show(SDL_Surface * to);
CSimpleWindow():bitmap(NULL),owner(NULL){}; //c-tor CSimpleWindow():bitmap(NULL){}; //c-tor
virtual ~CSimpleWindow(); //d-tor virtual ~CSimpleWindow(); //d-tor
void activate(){};
void deactivate(){};
}; };
class CPicture : public CIntObject class CPicture : public CIntObject
{ {
public: public:
SDL_Surface *bg; SDL_Surface *bg;
bool freeSurf; Rect *srcRect; //if NULL then whole surface will be used
bool freeSurf; //whether surface will be freed upon CPicture destruction
operator SDL_Surface*() operator SDL_Surface*()
{ {
return bg; return bg;
} }
CPicture(const Rect &r, const SDL_Color &color, bool screenFormat = false); CPicture(const Rect &r, const SDL_Color &color, bool screenFormat = false); //rect filled with given color
CPicture(const Rect &r, ui32 color, bool screenFormat = false); CPicture(const Rect &r, ui32 color, bool screenFormat = false); //rect filled with given color
CPicture(SDL_Surface *BG, int x, int y, bool Free = true); CPicture(SDL_Surface *BG, int x, int y, bool Free = true); //wrap existing SDL_Surface
CPicture(const std::string &bmpname, int x=0, int y=0); CPicture(const std::string &bmpname, int x=0, int y=0);
CPicture(SDL_Surface *BG, const Rect &SrcRext, int x = 0, int y = 0, bool free = false); //wrap subrect of given surface
void init();
void createSimpleRect(const Rect &r, bool screenFormat, ui32 color); void createSimpleRect(const Rect &r, bool screenFormat, ui32 color);
~CPicture(); ~CPicture();
@ -504,7 +520,7 @@ SDLKey arrowToNum(SDLKey key); //converts arrow key to according numpad key
SDLKey numToDigit(SDLKey key);//converts numpad digit key to normal digit key SDLKey numToDigit(SDLKey key);//converts numpad digit key to normal digit key
bool isNumKey(SDLKey key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits) bool isNumKey(SDLKey key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
bool isArrowKey(SDLKey key); bool isArrowKey(SDLKey key);
CIntObject * moveChildren(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos = false); CIntObject * moveChild(CIntObject *obj, CIntObject *from, CIntObject *to, bool adjustPos = false);
template <typename T> void pushIntT() template <typename T> void pushIntT()
{ {
@ -529,5 +545,6 @@ struct SetCaptureState
#define OBJ_CONSTRUCTION ObjectConstruction obj__i(this) #define OBJ_CONSTRUCTION ObjectConstruction obj__i(this)
#define OBJ_CONSTRUCTION_CAPTURING_ALL defActions = 255; SetCaptureState obj__i1(true, 255); ObjectConstruction obj__i(this) #define OBJ_CONSTRUCTION_CAPTURING_ALL defActions = 255; SetCaptureState obj__i1(true, 255); ObjectConstruction obj__i(this)
#define BLOCK_CAPTURING SetCaptureState obj__i(false, 0) #define BLOCK_CAPTURING SetCaptureState obj__i(false, 0)
#define BLOCK_CAPTURING_DONT_TOUCH_REC_ACTIONS SetCaptureState obj__i(false, GH.defActionsDef)
#endif //__GUIBASE_H__ #endif //__GUIBASE_H__

View File

@ -612,9 +612,9 @@ void CGarrisonInt::deactivate()
splitButtons[i]->deactivate(); splitButtons[i]->deactivate();
} }
CInfoWindow::CInfoWindow(std::string text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps) CInfoWindow::CInfoWindow(std::string Text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps)
{ {
slider = NULL; OBJ_CONSTRUCTION_CAPTURING_ALL;
ID = -1; ID = -1;
this->delComps = delComps; this->delComps = delComps;
for(int i=0;i<Buttons.size();i++) for(int i=0;i<Buttons.size();i++)
@ -623,19 +623,26 @@ CInfoWindow::CInfoWindow(std::string text, int player, int charperline, const st
buttons[i]->callback.add(Buttons[i].second); //each button will close the window apart from call-defined actions buttons[i]->callback.add(Buttons[i].second); //each button will close the window apart from call-defined actions
} }
text = new CTextBox(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, zwykly);
text->redrawParentOnScrolling = true;
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
for(int i=0;i<comps.size();i++) for(int i=0;i<comps.size();i++)
{ {
comps[i]->recActions = 0xff;
addChild(comps[i]);
components.push_back(comps[i]); components.push_back(comps[i]);
} }
CMessage::drawIWindow(this,text,player,charperline); CMessage::drawIWindow(this,Text,player,charperline);
} }
CInfoWindow::CInfoWindow() CInfoWindow::CInfoWindow()
{ {
ID = -1; ID = -1;
delComps = false; delComps = false;
text = NULL;
} }
void CInfoWindow::close() void CInfoWindow::close()
{ {
@ -645,54 +652,22 @@ void CInfoWindow::close()
} }
void CInfoWindow::show(SDL_Surface * to) void CInfoWindow::show(SDL_Surface * to)
{ {
CSimpleWindow::show(to); CIntObject::show(to);
for(int i=0;i<buttons.size();i++)
buttons[i]->show(to);
if (slider)
slider->show(to);
} }
CInfoWindow::~CInfoWindow() CInfoWindow::~CInfoWindow()
{ {
if(delComps) // if(delComps)
{ // {
for (int i=0;i<components.size();i++) // for (int i=0;i<components.size();i++)
delete components[i]; // delete components[i];
} // }
for(int i=0;i<buttons.size();i++)
delete buttons[i];
if (slider)
delete slider;
}
void CInfoWindow::activate()
{
for (int i=0;i<components.size();i++)
components[i]->activate();
for(int i=0;i<buttons.size();i++)
buttons[i]->activate();
if (slider)
slider->activate();
}
void CInfoWindow::sliderMoved(int to)
{
/*slider->moveTo(to);
if(!slider) return; //ignore spurious call when slider is being created
*/
redraw();
}
void CInfoWindow::deactivate()
{
for (int i=0;i<components.size();i++)
components[i]->deactivate();
for(int i=0;i<buttons.size();i++)
buttons[i]->deactivate();
if (slider)
slider->deactivate();
} }
void CInfoWindow::showAll( SDL_Surface * to ) void CInfoWindow::showAll( SDL_Surface * to )
{ {
show(to); CSimpleWindow::show(to);
CIntObject::showAll(to);
} }
void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<SComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, int player) void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<SComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, int player)
@ -1088,6 +1063,7 @@ void CSelectableComponent::show(SDL_Surface * to)
} }
void CSimpleWindow::show(SDL_Surface * to) void CSimpleWindow::show(SDL_Surface * to)
{ {
if(bitmap)
blitAt(bitmap,pos.x,pos.y,to); blitAt(bitmap,pos.x,pos.y,to);
} }
CSimpleWindow::~CSimpleWindow() CSimpleWindow::~CSimpleWindow()
@ -1129,6 +1105,8 @@ CSelWindow::CSelWindow(const std::string &text, int player, int charperline, con
for(int i=0;i<comps.size();i++) for(int i=0;i<comps.size();i++)
{ {
comps[i]->recActions = 255;
addChild(comps[i]);
components.push_back(comps[i]); components.push_back(comps[i]);
comps[i]->onSelect = boost::bind(&CSelWindow::selectionChange,this,i); comps[i]->onSelect = boost::bind(&CSelWindow::selectionChange,this,i);
if(i<9) if(i<9)
@ -2932,8 +2910,11 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
if(printButtonFor(RESOURCE_RESOURCE)) if(printButtonFor(RESOURCE_RESOURCE))
new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_RESOURCE), 516, 450,"TPMRKBU5.DEF"); new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_RESOURCE), 516, 450,"TPMRKBU5.DEF");
if(printButtonFor(CREATURE_RESOURCE)) if(printButtonFor(CREATURE_RESOURCE))
new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, CREATURE_RESOURCE), 516, 450,"TPMRKBU4.DEF"); new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, CREATURE_RESOURCE), 516, 485,"TPMRKBU4.DEF"); //was y=450, changed to not overlap res-res in some conditions
if(printButtonFor(RESOURCE_ARTIFACT))
new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_ARTIFACT), 18, 450,"TPMRKBU2.DEF");
if(printButtonFor(ARTIFACT_RESOURCE)) //unblock when support for art-res is ready
(new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_ARTIFACT), 18, 485,"TPMRKBU3.DEF"))->block(true); //was y=450, changed to not overlap res-res in some conditions
} }
@ -3212,7 +3193,7 @@ void CMarketplaceWindow::setMode(EMarketMode Mode)
bool CMarketplaceWindow::printButtonFor(EMarketMode M) const bool CMarketplaceWindow::printButtonFor(EMarketMode M) const
{ {
return market->allowsTrade(M) && M != mode && (hero || mode != CREATURE_RESOURCE); return market->allowsTrade(M) && M != mode && (hero || mode != CREATURE_RESOURCE && mode != RESOURCE_ARTIFACT && mode != ARTIFACT_RESOURCE);
} }
void CMarketplaceWindow::garrisonChanged() void CMarketplaceWindow::garrisonChanged()
@ -5577,11 +5558,19 @@ void MoraleLuckBox::set(bool morale, const CGHeroInstance *hero)
void CLabel::showAll(SDL_Surface * to) void CLabel::showAll(SDL_Surface * to)
{ {
CIntObject::showAll(to); CIntObject::showAll(to);
if(!text.length()) std::string *hlpText = NULL; //if NULL, text field will be used
if(ignoreLeadingWhitespace)
{
hlpText = new std::string(text);
boost::trim_left(*hlpText);
}
std::string &toPrint = hlpText ? *hlpText : text;
if(!toPrint.length())
return; return;
static void (*printer[3])(const std::string &, int, int, EFonts, SDL_Color, SDL_Surface *, bool) = {&CSDL_Ext::printAt, &CSDL_Ext::printAtMiddle, &CSDL_Ext::printTo}; //array of printing functions static void (*printer[3])(const std::string &, int, int, EFonts, SDL_Color, SDL_Surface *, bool) = {&CSDL_Ext::printAt, &CSDL_Ext::printAtMiddle, &CSDL_Ext::printTo}; //array of printing functions
printer[alignment](text, pos.x + textOffset.x, pos.y + textOffset.y, font, color, to, false); printer[alignment](toPrint, pos.x + textOffset.x, pos.y + textOffset.y, font, color, to, false);
} }
CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= zwykly*/, const std::string &Text /*= ""*/) CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= zwykly*/, const std::string &Text /*= ""*/)
@ -5606,6 +5595,88 @@ void CLabel::setTxt(const std::string &Txt)
} }
} }
CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= zwykly*/)
:CLabel(rect.x, rect.y, Font, Align, Color, Text), slider(NULL), sliderStyle(SliderStyle)
{
redrawParentOnScrolling = false;
autoRedraw = false;
pos.h = rect.h;
pos.w = rect.w;
assert(Align == TOPLEFT || Align == CENTER); //TODO: support for other alignments
assert(pos.w >= 80); //we need some space
setTxt(Text);
}
void CTextBox::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
const Font &f = *graphics->fonts[font];
int dy = f.height; //line height
int base_y = pos.y;
if(alignment == CENTER)
base_y += (pos.h - maxH)/2;
int howManyLinesToPrint = slider ? slider->capacity : lines.size();
int firstLineToPrint = slider ? slider->value : 0;
for (int i = 0; i < howManyLinesToPrint; i++)
{
const std::string &line = lines[i + firstLineToPrint];
int x = pos.x;
if(alignment == CENTER)
x += (pos.w - f.getWidth(line.c_str())) / 2;
printAt(line, pos.x, base_y + i*dy, font, color, to);
}
}
void CTextBox::setTxt(const std::string &Txt)
{
recalculateLines(Txt);
CLabel::setTxt(Txt);
}
void CTextBox::sliderMoved(int to)
{
if(redrawParentOnScrolling)
parent->redraw();
redraw();
}
void CTextBox::setBounds(int limitW, int limitH)
{
pos.h = limitH;
pos.w = limitW;
recalculateLines(text);
}
void CTextBox::recalculateLines(const std::string &Txt)
{
delChildNUll(slider, true);
lines.clear();
const Font &f = *graphics->fonts[font];
int lineHeight = f.height;
int lineCapacity = pos.h / lineHeight;
lines = CMessage::breakText(Txt, pos.w, font);
if(lines.size() > lineCapacity) //we need to add a slider
{
lines = CMessage::breakText(Txt, pos.w - 32 - 10, font);
OBJ_CONSTRUCTION_CAPTURING_ALL;
slider = new CSlider(pos.w - 32, 0, pos.h, boost::bind(&CTextBox::sliderMoved, this, _1), lineCapacity, lines.size(), 0, false, sliderStyle);
if(active)
slider->activate();
}
maxH = lineHeight * lines.size();
maxW = 0;
BOOST_FOREACH(const std::string &line, lines)
amax(maxW, f.getWidth(line.c_str()));
}
void CGStatusBar::print(const std::string & Text) void CGStatusBar::print(const std::string & Text)
{ {
setTxt(Text); setTxt(Text);
@ -5632,7 +5703,7 @@ CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font /*= FONT_SMALL*/, EAlignment
{ {
init(); init();
bg = BG; bg = BG;
moveChildren(bg, bg->parent, this); moveChild(bg, bg->parent, this);
pos = bg->pos; pos = bg->pos;
switch(Align) switch(Align)

View File

@ -66,23 +66,22 @@ struct SPuzzleInfo;
class CGGarrison; class CGGarrison;
class CStackInstance; class CStackInstance;
class IMarket; class IMarket;
class CTextBox;
extern SDL_Color tytulowy, tlo, zwykly ; extern SDL_Color tytulowy, tlo, zwykly ;
class CInfoWindow : public CSimpleWindow //text + comp. + ok button class CInfoWindow : public CSimpleWindow //text + comp. + ok button
{ //window able to delete its components when closed { //window able to delete its components when closed
public: public:
bool delComps; //whether comps will be deleted CTextBox *text;
std::vector<AdventureMapButton *> buttons; std::vector<AdventureMapButton *> buttons;
bool delComps; //whether comps will be deleted
std::vector<SComponent*> components; std::vector<SComponent*> components;
CSlider *slider;
virtual void close(); virtual void close();
void show(SDL_Surface * to); void show(SDL_Surface * to);
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
void activate(); CInfoWindow(std::string Text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps); //c-tor
void sliderMoved(int to);
void deactivate();
CInfoWindow(std::string text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps); //c-tor
CInfoWindow(); //c-tor CInfoWindow(); //c-tor
~CInfoWindow(); //d-tor ~CInfoWindow(); //d-tor
@ -282,14 +281,39 @@ public:
SDL_Color color; SDL_Color color;
std::string text; std::string text;
CPicture *bg; CPicture *bg;
bool autoRedraw; bool autoRedraw; //whether control will redraw itself on setTxt
Point textOffset; //text will be blitted at pos + textOffset with appropriate alignment Point textOffset; //text will be blitted at pos + textOffset with appropriate alignment
bool ignoreLeadingWhitespace;
void setTxt(const std::string &Txt); virtual void setTxt(const std::string &Txt);
void showAll(SDL_Surface * to); //shows statusbar (with current text) void showAll(SDL_Surface * to); //shows statusbar (with current text)
CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly, const std::string &Text = ""); CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly, const std::string &Text = "");
}; };
//a multi-line label that tries to fit text with given available width and height; if not possible, it creates a slider for scrolling text
class CTextBox
: public CLabel
{
public:
int maxW; //longest line of text in px
int maxH; //total height needed to print all lines
int sliderStyle;
bool redrawParentOnScrolling;
std::vector<std::string> lines;
CSlider *slider;
//CTextBox( std::string Text, const Point &Pos, int w, int h, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly);
CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = zwykly);
void showAll(SDL_Surface * to); //shows statusbar (with current text)
void setTxt(const std::string &Txt);
void setBounds(int limitW, int limitH);
void recalculateLines(const std::string &Txt);
void sliderMoved(int to);
};
class CGStatusBar class CGStatusBar
: public CLabel, public IStatusBar : public CLabel, public IStatusBar
{ {

View File

@ -713,6 +713,13 @@ int Font::getWidth(const char *text ) const
return ret; return ret;
} }
int Font::getCharWidth( char c ) const
{
const Char &C = chars[(unsigned char)c];
return C.width + C.unknown1 + C.unknown2;;
}
/* /*
void Font::WriteAt(const char *text, SDL_Surface *sur, int x, int y ) void Font::WriteAt(const char *text, SDL_Surface *sur, int x, int y )
{ {

View File

@ -25,25 +25,6 @@ struct SDL_Color;
struct InfoAboutHero; struct InfoAboutHero;
struct InfoAboutTown; struct InfoAboutTown;
struct Font
{
struct Char
{
si32 unknown1, width, unknown2, offset;
unsigned char *pixels;
};
Char chars[256];
ui8 height;
unsigned char *data;
Font(unsigned char *Data);
~Font();
int getWidth(const char *text) const;
};
class Graphics class Graphics
{ {
public: public:

View File

@ -80,12 +80,12 @@ void updateRect (SDL_Rect * rect, SDL_Surface * scr)
void printAtMiddleWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst) void printAtMiddleWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{ {
std::vector<std::string> * ws = CMessage::breakText(text,charpr); std::vector<std::string> ws = CMessage::breakText(text,charpr);
std::vector<SDL_Surface*> wesu; std::vector<SDL_Surface*> wesu;
wesu.resize(ws->size()); wesu.resize(ws.size());
for (size_t i=0; i < wesu.size(); ++i) for (size_t i=0; i < wesu.size(); ++i)
{ {
wesu[i]=TTF_RenderText_Blended(font,(*ws)[i].c_str(),kolor); wesu[i]=TTF_RenderText_Blended(font,ws[i].c_str(),kolor);
} }
int tox=0, toy=0; int tox=0, toy=0;
@ -106,16 +106,15 @@ void printAtMiddleWB(const std::string & text, int x, int y, TTF_Font * font, in
for (size_t i=0; i < wesu.size(); ++i) for (size_t i=0; i < wesu.size(); ++i)
SDL_FreeSurface(wesu[i]); SDL_FreeSurface(wesu[i]);
delete ws;
} }
void printAtWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst) void printAtWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{ {
std::vector<std::string> * ws = CMessage::breakText(text,charpr); std::vector<std::string> ws = CMessage::breakText(text,charpr);
std::vector<SDL_Surface*> wesu; std::vector<SDL_Surface*> wesu;
wesu.resize(ws->size()); wesu.resize(ws.size());
for (size_t i=0; i < wesu.size(); ++i) for (size_t i=0; i < wesu.size(); ++i)
wesu[i]=TTF_RenderText_Blended(font,(*ws)[i].c_str(),kolor); wesu[i]=TTF_RenderText_Blended(font,ws[i].c_str(),kolor);
int evy = y; int evy = y;
for (size_t i=0; i < wesu.size(); ++i) for (size_t i=0; i < wesu.size(); ++i)
@ -126,7 +125,6 @@ void printAtWB(const std::string & text, int x, int y, TTF_Font * font, int char
for (size_t i=0; i < wesu.size(); ++i) for (size_t i=0; i < wesu.size(); ++i)
SDL_FreeSurface(wesu[i]); SDL_FreeSurface(wesu[i]);
delete ws;
} }
void CSDL_Ext::printAtWB(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst, bool refresh) void CSDL_Ext::printAtWB(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst, bool refresh)
@ -137,15 +135,14 @@ void CSDL_Ext::printAtWB(const std::string & text, int x, int y, EFonts font, in
return; return;
} }
const Font *f = graphics->fonts[font]; const Font *f = graphics->fonts[font];
std::vector<std::string> * ws = CMessage::breakText(text,charpr); std::vector<std::string> ws = CMessage::breakText(text,charpr);
int cury = y; int cury = y;
for (size_t i=0; i < ws->size(); ++i) for (size_t i=0; i < ws.size(); ++i)
{ {
printAt((*ws)[i], x, cury, font, kolor, dst, refresh); printAt(ws[i], x, cury, font, kolor, dst, refresh);
cury += f->height; cury += f->height;
} }
delete ws;
} }
@ -158,16 +155,15 @@ void CSDL_Ext::printAtMiddleWB( const std::string & text, int x, int y, EFonts f
} }
const Font *f = graphics->fonts[font]; const Font *f = graphics->fonts[font];
std::vector<std::string> * ws = CMessage::breakText(text,charpr); std::vector<std::string> ws = CMessage::breakText(text,charpr);
int totalHeight = ws->size() * f->height; int totalHeight = ws.size() * f->height;
int cury = y - totalHeight/2; int cury = y - totalHeight/2;
for (size_t i=0; i < ws->size(); ++i) for (size_t i=0; i < ws.size(); ++i)
{ {
printAt((*ws)[i], x - f->getWidth((*ws)[i].c_str())/2, cury, font, kolor, dst, refrsh); printAt(ws[i], x - f->getWidth(ws[i].c_str())/2, cury, font, kolor, dst, refrsh);
cury += f->height; cury += f->height;
} }
delete ws;
} }
void printAtMiddle(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, unsigned char quality=2, bool refresh=false) void printAtMiddle(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, unsigned char quality=2, bool refresh=false)

View File

@ -5459,7 +5459,7 @@ void CGPyramid::endBattle (const CGHeroInstance *h, const BattleResult *result)
void CGKeys::setPropertyDer (ui8 what, ui32 val) //101-108 - enable key for player 1-8 void CGKeys::setPropertyDer (ui8 what, ui32 val) //101-108 - enable key for player 1-8
{ {
if (what >= 101 && what <= (100 + PLAYER_LIMIT)) if (what >= 101 && what <= (100 + PLAYER_LIMIT))
playerKeyMap.find(what-101)->second.insert(val); playerKeyMap.find(what-101)->second.insert((ui8)val);
} }
bool CGKeys::wasMyColorVisited (int player) const bool CGKeys::wasMyColorVisited (int player) const
@ -6222,6 +6222,7 @@ const IMarket * IMarket::castFrom(const CGObjectInstance *obj)
{ {
case TOWNI_TYPE: case TOWNI_TYPE:
return static_cast<const CGTownInstance*>(obj); return static_cast<const CGTownInstance*>(obj);
case 2: //Altar of Sacrifice
case 7: //Black Market case 7: //Black Market
case 99: //Trading Post case 99: //Trading Post
case 221: //Trading Post (snow) case 221: //Trading Post (snow)
@ -6282,6 +6283,9 @@ bool CGMarket::allowsTrade(EMarketMode mode) const
case ARTIFACT_RESOURCE: case ARTIFACT_RESOURCE:
case RESOURCE_ARTIFACT: case RESOURCE_ARTIFACT:
return ID == 7; //Black Market return ID == 7; //Black Market
case ARTIFACT_EXP:
case CREATURE_EXP:
return ID == 2; //TODO? check here for alignment of visiting hero? - would not be coherent with other checks here
} }
return false; return false;
} }

View File

@ -1444,24 +1444,26 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
} }
case bartifact: case bartifact:
{ {
if(!k->second.heroes.size()) //TODO: FIX IT!
{
tlog5 << "Cannot give starting artifact - no heroes!" << std::endl; // if(!k->second.heroes.size())
break; // {
} // tlog5 << "Cannot give starting artifact - no heroes!" << std::endl;
CArtifact *toGive; // break;
do // }
{ // CArtifact *toGive;
toGive = VLC->arth->treasures[ran() % VLC->arth->treasures.size()]; // do
} while (!map->allowedArtifact[toGive->id]); // {
CGHeroInstance *hero = k->second.heroes[0]; // toGive = VLC->arth->treasures[ran() % VLC->arth->treasures.size()];
std::vector<ui16>::iterator slot = vstd::findFirstNot(hero->artifWorn,toGive->possibleSlots); // } while (!map->allowedArtifact[toGive->id]);
if(slot!=toGive->possibleSlots.end()) // CGHeroInstance *hero = k->second.heroes[0];
{ // std::vector<ui16>::iterator slot = vstd::findFirstNot(hero->artifWorn,toGive->possibleSlots);
VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id, &hero->bonuses); // if(slot!=toGive->possibleSlots.end())
} // {
else // VLC->arth->equipArtifact(hero->artifWorn, *slot, toGive->id, &hero->bonuses);
hero->giveArtifact(toGive->id); // }
// else
// hero->giveArtifact(toGive->id);
} }
} }
} }

View File

@ -1953,7 +1953,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
nobj->tempOwner = readNormalNr(bufor,i); i+=4; nobj->tempOwner = readNormalNr(bufor,i); i+=4;
break; break;
} }
//case 2: //Altar of Sacrifice case 2: //Altar of Sacrifice
case 99: //Trading Post case 99: //Trading Post
case 213: //Freelancer's Guild case 213: //Freelancer's Guild
case 221: //Trading Post (snow) case 221: //Trading Post (snow)