1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-15 01:24:45 +02:00

CButton GUI class (partial rewrite of CAdventureButton),

bugs fixes, warnings elimination
This commit is contained in:
paracelsus
2013-03-10 18:26:10 +00:00
parent d4a74b536d
commit 6cef1dd8d8
26 changed files with 323 additions and 267 deletions

View File

@ -1658,7 +1658,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
//displaying animation //displaying animation
CDefEssential * animDef = CDefHandler::giveDefEss(animToDisplay); CDefEssential * animDef = CDefHandler::giveDefEss(animToDisplay);
int steps = sqrt(static_cast<double>((destcoord.x - srccoord.x)*(destcoord.x - srccoord.x) + (destcoord.y - srccoord.y) * (destcoord.y - srccoord.y))) / 40; int steps = (int)sqrt(static_cast<double>((destcoord.x - srccoord.x)*(destcoord.x - srccoord.x) + (destcoord.y - srccoord.y) * (destcoord.y - srccoord.y))) / 40;
if(steps <= 0) if(steps <= 0)
steps = 1; steps = 1;

View File

@ -263,11 +263,9 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt
animSpeeds->onChange = boost::bind(&CBattleInterface::setAnimSpeed, owner, _1); animSpeeds->onChange = boost::bind(&CBattleInterface::setAnimSpeed, owner, _1);
setToDefault = new CAdventureMapButton (CGI->generaltexth->zelp[393], boost::bind(&CBattleOptionsWindow::bDefaultf,this), 246, 359, "codefaul.def"); setToDefault = new CAdventureMapButton (CGI->generaltexth->zelp[393], boost::bind(&CBattleOptionsWindow::bDefaultf,this), 246, 359, "codefaul.def");
setToDefault->swappedImages = true; setToDefault->swapImages();
setToDefault->update();
exit = new CAdventureMapButton (CGI->generaltexth->zelp[392], boost::bind(&CBattleOptionsWindow::bExitf,this), 357, 359, "soretrn.def",SDLK_RETURN); exit = new CAdventureMapButton (CGI->generaltexth->zelp[392], boost::bind(&CBattleOptionsWindow::bExitf,this), 357, 359, "soretrn.def",SDLK_RETURN);
exit->swappedImages = true; exit->swapImages();
exit->update();
//creating labels //creating labels
labels.push_back(new CLabel(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[392]));//window title labels.push_back(new CLabel(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[392]));//window title
@ -615,7 +613,7 @@ void CStackQueue::update()
owner->curInt->cb->battleGetStackQueue(stacksSorted, stackBoxes.size()); owner->curInt->cb->battleGetStackQueue(stacksSorted, stackBoxes.size());
if(stacksSorted.size()) if(stacksSorted.size())
{ {
for (int i = 0; i < stackBoxes.size() ; i++) for (size_t i = 0; i < stackBoxes.size(); ++i)
{ {
stackBoxes[i]->setStack(stacksSorted[i]); stackBoxes[i]->setStack(stacksSorted[i]);
} }
@ -646,7 +644,7 @@ CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
} }
stackBoxes.resize(QUEUE_SIZE); stackBoxes.resize(QUEUE_SIZE);
for (int i = 0; i < stackBoxes.size(); i++) for (size_t i = 0; i < stackBoxes.size(); ++i)
{ {
stackBoxes[i] = new StackBox(embedded); stackBoxes[i] = new StackBox(embedded);
stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80)*i, 0)); stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80)*i, 0));

View File

@ -543,7 +543,6 @@ void CAdvMapInt::updateSleepWake(const CGHeroInstance *h)
sleepWake.setIndex(state ? 1 : 0, true); sleepWake.setIndex(state ? 1 : 0, true);
sleepWake.assignedKeys.clear(); sleepWake.assignedKeys.clear();
sleepWake.assignedKeys.insert(state ? SDLK_w : SDLK_z); sleepWake.assignedKeys.insert(state ? SDLK_w : SDLK_z);
sleepWake.update();
} }
void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath) void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath)

View File

@ -959,7 +959,7 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
return; return;
} }
std::vector<CComponent*> intComps; std::vector<CComponent*> intComps;
for(int i=0;i<components.size();i++) for(size_t i=0; i<components.size(); ++i)
intComps.push_back(new CComponent(*components[i])); intComps.push_back(new CComponent(*components[i]));
showInfoDialog(text,intComps,soundID); showInfoDialog(text,intComps,soundID);
@ -1016,7 +1016,7 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
if(!selection && cancel) //simple yes/no dialog if(!selection && cancel) //simple yes/no dialog
{ {
std::vector<CComponent*> intComps; std::vector<CComponent*> intComps;
for(int i=0;i<components.size();i++) for(size_t i=0; i<components.size(); ++i)
intComps.push_back(new CComponent(components[i])); //will be deleted by close in window intComps.push_back(new CComponent(components[i])); //will be deleted by close in window
showYesNoDialog(text, boost::bind(&CCallback::selectionMade,cb,1,askID),boost::bind(&CCallback::selectionMade,cb,0,askID),true, intComps); showYesNoDialog(text, boost::bind(&CCallback::selectionMade,cb,1,askID),boost::bind(&CCallback::selectionMade,cb,0,askID),true, intComps);
@ -1024,7 +1024,7 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
else if(selection) else if(selection)
{ {
std::vector<CSelectableComponent*> intComps; std::vector<CSelectableComponent*> intComps;
for(int i=0;i<components.size();i++) for(size_t i=0; i<components.size(); ++i)
intComps.push_back(new CSelectableComponent(components[i])); //will be deleted by CSelWindow::close intComps.push_back(new CSelectableComponent(components[i])); //will be deleted by CSelWindow::close
std::vector<std::pair<std::string,CFunctionList<void()> > > pom; std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
@ -1438,7 +1438,7 @@ void CPlayerInterface::initializeHeroTownList()
wanderingHeroes = newWanderingHeroes; wanderingHeroes = newWanderingHeroes;
newWanderingHeroes.clear();*/ newWanderingHeroes.clear();*/
for (int i = 0; i < allHeroes.size(); i++) for (size_t i = 0; i < allHeroes.size(); ++i)
if (!allHeroes[i]->inTownGarrison) if (!allHeroes[i]->inTownGarrison)
wanderingHeroes += allHeroes[i]; wanderingHeroes += allHeroes[i];
@ -1455,7 +1455,7 @@ void CPlayerInterface::initializeHeroTownList()
towns.clear(); towns.clear();
towns = newTowns; towns = newTowns;
newTowns.clear();*/ newTowns.clear();*/
for(int i = 0; i < allTowns.size(); i++) for(size_t i = 0; i < allTowns.size(); ++i)
towns.push_back(allTowns[i]); towns.push_back(allTowns[i]);
if (adventureInt) if (adventureInt)

View File

@ -39,6 +39,7 @@
#include "../lib/CThreadHelper.h" #include "../lib/CThreadHelper.h"
#include "../lib/CConfigHandler.h" #include "../lib/CConfigHandler.h"
#include "../lib/GameConstants.h" #include "../lib/GameConstants.h"
#include "Gfx/Basic.h"
#include "UIFramework/GL2D.h" #include "UIFramework/GL2D.h"
#include "UIFramework/CGuiHandler.h" #include "UIFramework/CGuiHandler.h"
#include "UIFramework/CIntObjectClasses.h" #include "UIFramework/CIntObjectClasses.h"
@ -368,23 +369,19 @@ static boost::function<void()> genCommand(CMenuScreen* menu, std::vector<std::st
return boost::function<void()>(); return boost::function<void()>();
} }
CAdventureMapButton* CMenuEntry::createButton(CMenuScreen* parent, const JsonNode& button) CButton* CMenuEntry::createButton(CMenuScreen* parent, const JsonNode& button)
{ {
boost::function<void()> command = genCommand(parent, parent->menuNameToEntry, button["command"].String()); boost::function<void()> command = genCommand(parent, parent->menuNameToEntry, button["command"].String());
std::pair<std::string, std::string> help; Gfx::Point point(button["x"].asInteger(), button["y"].asInteger());
if (!button["help"].isNull() && button["help"].Float() > 0)
help = CGI->generaltexth->zelp[button["help"].Float()];
int posx = button["x"].Float(); if (point.x < 0) point.x += pos.w;
if (posx < 0) if (point.y < 0) point.y += pos.h;
posx = pos.w + posx;
int posy = button["y"].Float(); const PairOfStrings * help = (button["help"].Float() > 0) ?
if (posy < 0) &( CGI->generaltexth->zelp[button["help"].asInteger()] ) : nullptr;
posy = pos.h + posy;
return new CAdventureMapButton(help, command, posx, posy, button["name"].String(), button["hotkey"].Float()); return new CButton(command, point, button["name"].String(), 0, 4, help, LCLICK|RCLICK|HOVER|KEYBOARD, button["hotkey"].asInteger());
} }
CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config) CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config)
@ -399,7 +396,6 @@ CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config)
BOOST_FOREACH(const JsonNode& node, config["buttons"].Vector()) BOOST_FOREACH(const JsonNode& node, config["buttons"].Vector())
{ {
buttons.push_back(createButton(parent, node)); buttons.push_back(createButton(parent, node));
buttons.back()->hoverable = true;
buttons.back()->type |= REDRAW_PARENT; buttons.back()->type |= REDRAW_PARENT;
} }
} }
@ -610,32 +606,35 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
sel = new SelectionTab(screenType, bind(&CSelectionScreen::changeSelection, this, _1), multiPlayer); //scenario selection tab sel = new SelectionTab(screenType, bind(&CSelectionScreen::changeSelection, this, _1), multiPlayer); //scenario selection tab
sel->recActions = DISPOSE; sel->recActions = DISPOSE;
auto & zelp = CGI->generaltexth->zelp;
switch(screenType) switch(screenType)
{ {
case CMenuScreen::newGame: case CMenuScreen::newGame:
{ {
card->difficulty->onChange = bind(&CSelectionScreen::difficultyChange, this, _1); card->difficulty->onChange = bind(&CSelectionScreen::difficultyChange, this, _1);
card->difficulty->select(1, 0); card->difficulty->select(1, 0);
CAdventureMapButton * select = new CAdventureMapButton(CGI->generaltexth->zelp[45], 0, 411, 80, "GSPBUTT.DEF", SDLK_s);
select->callback = [&]() const CFunctionList<void()> selectCmd = [&]()
{ {
toggleTab(sel); toggleTab(sel);
changeSelection(sel->getSelectedMapInfo()); changeSelection(sel->getSelectedMapInfo());
}; };
CButton * select = new CButton(selectCmd, Gfx::Point(411, 80), "GSPBUTT", 0, 4, &(zelp[45]), LCLICK|RCLICK|KEYBOARD, SDLK_s);
select->addTextOverlay(CGI->generaltexth->allTexts[500], FONT_SMALL); select->addTextOverlay(CGI->generaltexth->allTexts[500], FONT_SMALL);
CAdventureMapButton *opts = new CAdventureMapButton(CGI->generaltexth->zelp[46], bind(&CSelectionScreen::toggleTab, this, opt), 411, 510, "GSPBUTT.DEF", SDLK_a); const CFunctionList<void()> randomCmd = [&]()
opts->addTextOverlay(CGI->generaltexth->allTexts[501], FONT_SMALL);
CAdventureMapButton * randomBtn = new CAdventureMapButton(CGI->generaltexth->zelp[47], 0, 411, 105, "GSPBUTT.DEF", SDLK_r);
randomBtn->addTextOverlay(CGI->generaltexth->allTexts[740], FONT_SMALL);
randomBtn->callback = [&]()
{ {
toggleTab(randMapTab); toggleTab(randMapTab);
changeSelection(&randMapTab->getMapInfo()); changeSelection(&randMapTab->getMapInfo());
}; };
CButton * randomBtn = new CButton(randomCmd, Gfx::Point(411, 105), "GSPBUTT", 0, 4, &(zelp[47]), LCLICK|RCLICK|KEYBOARD, SDLK_r);
randomBtn->addTextOverlay(CGI->generaltexth->allTexts[740], FONT_SMALL);
start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRBEG.DEF", SDLK_b); CButton * opts = new CButton(bind(&CSelectionScreen::toggleTab, this, opt), Gfx::Point(411, 510), "GSPBUTT", 0, 4, &(zelp[46]), LCLICK|RCLICK|KEYBOARD, SDLK_a);
opts->addTextOverlay(CGI->generaltexth->allTexts[501], FONT_SMALL);
start = new CButton(bind(&CSelectionScreen::startScenario, this), Gfx::Point(411, 535), "SCNRBEG", 0, 4, &(zelp[103]), LCLICK|RCLICK|KEYBOARD, SDLK_b);
if(network) if(network)
{ {
@ -656,31 +655,21 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
break; break;
case CMenuScreen::loadGame: case CMenuScreen::loadGame:
sel->recActions = 255; sel->recActions = 255;
start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRLOD.DEF", SDLK_l); start = new CButton(bind(&CSelectionScreen::startScenario, this), Gfx::Point(411, 535), "SCNRLOD", 0, 4, &(zelp[103]), LCLICK|RCLICK|KEYBOARD, SDLK_l);
break; break;
case CMenuScreen::saveGame: case CMenuScreen::saveGame:
sel->recActions = 255; sel->recActions = 255;
start = new CAdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startScenario, this), 411, 535, "SCNRSAV.DEF"); start = new CButton(bind(&CSelectionScreen::startScenario, this), Gfx::Point(411, 535), "SCNRSAV", 0, 4, &(zelp[103]), LCLICK|RCLICK|KEYBOARD);
break; break;
case CMenuScreen::campaignList: case CMenuScreen::campaignList:
sel->recActions = 255; sel->recActions = 255;
start = new CAdventureMapButton(std::pair<std::string, std::string>(), bind(&CSelectionScreen::startCampaign, this), 411, 535, "SCNRLOD.DEF", SDLK_b); start = new CButton(bind(&CSelectionScreen::startCampaign, this), Gfx::Point(411, 535), "SCNRLOD", 0, 4, nullptr, LCLICK|RCLICK|KEYBOARD, SDLK_b);
break; break;
} }
start->assignedKeys.insert(SDLK_RETURN); start->assignedKeys.insert(SDLK_RETURN);
std::string backName; back = new CButton( bind(&CGuiHandler::popIntTotally, &GH, this), Gfx::Point(581, 535), "SCNRBACK", 0, 2, &(zelp[105]), LCLICK|RCLICK|KEYBOARD, SDLK_ESCAPE);
if(Type == CMenuScreen::campaignList)
{
backName = "SCNRBACK.DEF";
}
else
{
backName = "SCNRBACK.DEF";
}
back = new CAdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 535, backName, SDLK_ESCAPE);
if(network) if(network)
{ {
@ -1084,7 +1073,7 @@ std::vector<ResourceID> SelectionTab::getFiles(std::string dirURI, int resType)
void SelectionTab::parseMaps(const std::vector<ResourceID> & files) void SelectionTab::parseMaps(const std::vector<ResourceID> & files)
{ {
allItems.clear(); allItems.clear();
for(int i = 0; i < files.size(); ++i) for(size_t i = 0; i < files.size(); ++i)
{ {
try try
{ {
@ -1245,7 +1234,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->addUsedEvents(WHEEL); slider->addUsedEvents(WHEEL);
slider->slider->keepFrame = true; //* slider->slider->keepFrame = true;
format = CDefHandler::giveDef("SCSELC.DEF"); format = CDefHandler::giveDef("SCSELC.DEF");
sortingBy = _format; sortingBy = _format;
@ -1733,14 +1722,14 @@ void RandomMapTab::deactivateButtonsFrom(CHighlightableButtonsGroup * group, int
if(btn->isBlocked()) if(btn->isBlocked())
{ {
btn->setOffset(0); btn->setOffset(0);
btn->setState(CButtonBase::NORMAL); btn->setState(CButton::NORMAL);
} }
} }
else else
{ {
// Blocked state looks like frame 'selected'=1 // Blocked state looks like frame 'selected'=1
btn->setOffset(-1); btn->setOffset(-1);
btn->setState(CButtonBase::BLOCKED); btn->setState(CButton::BLOCKED);
} }
} }
} }
@ -3271,8 +3260,8 @@ void CBonusSelection::loadPositionsOfGraphics()
SCampPositions::SRegionDesc rd; SCampPositions::SRegionDesc rd;
rd.infix = desc["infix"].String(); rd.infix = desc["infix"].String();
rd.xpos = desc["x"].Float(); rd.xpos = desc["x"].asInteger();
rd.ypos = desc["y"].Float(); rd.ypos = desc["y"].asInteger();
sc.regions.push_back(rd); sc.regions.push_back(rd);
} }
@ -3634,9 +3623,9 @@ void CBonusSelection::changeDiff( bool increase )
void CBonusSelection::updateStartButtonState( int selected /*= -1*/ ) void CBonusSelection::updateStartButtonState( int selected /*= -1*/ )
{ {
if(selected == -1) if(selected == -1)
startB->setState( ourCampaign->getCurrentScenario().travelOptions.bonusesToChoose.size() ? CButtonBase::BLOCKED : CButtonBase::NORMAL); startB->block( ourCampaign->getCurrentScenario().travelOptions.bonusesToChoose.size());
else if(startB->getState() == CButtonBase::BLOCKED) else if(startB->isBlocked())
startB->setState(CButtonBase::NORMAL); startB->setState(CButton::NORMAL);
} }
CBonusSelection::CRegion::CRegion( CBonusSelection * _owner, bool _accessible, bool _selectable, int _myNumber ) CBonusSelection::CRegion::CRegion( CBonusSelection * _owner, bool _accessible, bool _selectable, int _myNumber )

View File

@ -80,9 +80,9 @@ public:
class CMenuEntry : public CIntObject class CMenuEntry : public CIntObject
{ {
std::vector<CPicture*> images; std::vector<CPicture*> images;
std::vector<CAdventureMapButton*> buttons; std::vector<CButton*> buttons;
CAdventureMapButton* createButton(CMenuScreen* parent, const JsonNode& button); CButton* createButton(CMenuScreen* parent, const JsonNode& button);
public: public:
CMenuEntry(CMenuScreen* parent, const JsonNode &config); CMenuEntry(CMenuScreen* parent, const JsonNode &config);
}; };
@ -453,7 +453,7 @@ public:
InfoCard *card; InfoCard *card;
OptionsTab *opt; OptionsTab *opt;
RandomMapTab * randMapTab; RandomMapTab * randMapTab;
CAdventureMapButton *start, *back; CButton *start, *back;
SelectionTab *sel; SelectionTab *sel;
CIntObject *curTab; CIntObject *curTab;

View File

@ -3470,32 +3470,27 @@ CSystemOptionsWindow::CSystemOptionsWindow():
//setting up buttons //setting up buttons
load = new CAdventureMapButton (CGI->generaltexth->zelp[321].first, CGI->generaltexth->zelp[321].second, load = new CAdventureMapButton (CGI->generaltexth->zelp[321].first, CGI->generaltexth->zelp[321].second,
boost::bind(&CSystemOptionsWindow::bloadf, this), 246, 298, "SOLOAD.DEF", SDLK_l); boost::bind(&CSystemOptionsWindow::bloadf, this), 246, 298, "SOLOAD.DEF", SDLK_l);
load->swappedImages = true; load->swapImages();
load->update();
save = new CAdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second, save = new CAdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second,
boost::bind(&CSystemOptionsWindow::bsavef, this), 357, 298, "SOSAVE.DEF", SDLK_s); boost::bind(&CSystemOptionsWindow::bsavef, this), 357, 298, "SOSAVE.DEF", SDLK_s);
save->swappedImages = true; save->swapImages();
save->update();
restart = new CAdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second, restart = new CAdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second,
boost::bind(&CSystemOptionsWindow::brestartf, this), 246, 357, "SORSTRT", SDLK_r); boost::bind(&CSystemOptionsWindow::brestartf, this), 246, 357, "SORSTRT", SDLK_r);
restart->swappedImages = true; restart->swapImages();
restart->update();
mainMenu = new CAdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second, mainMenu = new CAdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second,
boost::bind(&CSystemOptionsWindow::bmainmenuf, this), 357, 357, "SOMAIN.DEF", SDLK_m); boost::bind(&CSystemOptionsWindow::bmainmenuf, this), 357, 357, "SOMAIN.DEF", SDLK_m);
mainMenu->swappedImages = true; mainMenu->swapImages();
mainMenu->update();
quitGame = new CAdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second, quitGame = new CAdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second,
boost::bind(&CSystemOptionsWindow::bquitf, this), 246, 415, "soquit.def", SDLK_q); boost::bind(&CSystemOptionsWindow::bquitf, this), 246, 415, "soquit.def", SDLK_q);
quitGame->swappedImages = true; quitGame->swapImages();
quitGame->update();
backToMap = new CAdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second, backToMap = new CAdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second,
boost::bind(&CSystemOptionsWindow::breturnf, this), 357, 415, "soretrn.def", SDLK_RETURN); boost::bind(&CSystemOptionsWindow::breturnf, this), 357, 415, "soretrn.def", SDLK_RETURN);
backToMap->swappedImages = true; backToMap->swapImages();
backToMap->update();
backToMap->assignedKeys.insert(SDLK_ESCAPE); backToMap->assignedKeys.insert(SDLK_ESCAPE);
heroMoveSpeed = new CHighlightableButtonsGroup(0); heroMoveSpeed = new CHighlightableButtonsGroup(0);

View File

@ -11,7 +11,7 @@ class CImage;
class CAnimation class CAnimation
{ {
protected: protected:
ui32 framesCount; size_t framesCount;
ui32 width; ui32 width;
ui32 height; ui32 height;
@ -23,7 +23,7 @@ public:
virtual ~CAnimation(); virtual ~CAnimation();
virtual CImage* getFrame(ui32 fnr) = 0; virtual CImage* getFrame(ui32 fnr) = 0;
inline ui32 getFramesCount() { return framesCount; }; inline size_t getFramesCount() { return framesCount; };
inline ui32 getWidth() { return width; }; inline ui32 getWidth() { return width; };
inline ui32 getHeight() { return height; }; inline ui32 getHeight() { return height; };
}; };
@ -57,7 +57,7 @@ class CPalettedAnimation : CAnimation
protected: protected:
CPalettedAnimation(const SH3DefFile& def, size_t fileSize); CPalettedAnimation(const SH3DefFile& def, size_t fileSize);
inline void* operator new(size_t size, ui32 frCount) { inline void* operator new(size_t size, size_t frCount) {
return ::operator new(size + frCount * sizeof(void*)); return ::operator new(size + frCount * sizeof(void*));
} }

View File

@ -2,6 +2,8 @@
#include <SDL_opengl.h> #include <SDL_opengl.h>
#include <SDL_endian.h> #include <SDL_endian.h>
#include "Images.h" #include "Images.h"
#include "../UIFramework/GL2D.h"
namespace Gfx namespace Gfx
{ {

View File

@ -1,31 +1,11 @@
#pragma once #pragma once
#include "Basic.h"
#include "CPaletteRGBA.h" #include "CPaletteRGBA.h"
#include "../UIFramework/GL2D.h"
namespace Gfx namespace Gfx
{ {
struct Point
{
si32 x;
si32 y;
inline Point() {};
inline Point(si32 _x, si32 _y) : x(_x), y(_y) {};
};
struct Rect
{
Point lt;
Point rb;
inline ui32 width() { return rb.x - lt.x; };
inline ui32 height() { return rb.y - lt.y; };
};
enum TransformFlags enum TransformFlags
{ {
NONE = 0, NONE = 0,
@ -34,9 +14,6 @@ enum TransformFlags
ROTATE_90_DEG = 4 ROTATE_90_DEG = 4
}; };
/* Color transform matrix for: grayscale, clone, bloodlust, etc */
typedef float ColorMatrix[4][4];
class CImage class CImage
{ {

View File

@ -199,95 +199,138 @@ void CFilledTexture::showAll()
//* CSDL_Ext::fillTexture(to, texture); //* CSDL_Ext::fillTexture(to, texture);
} }
CButtonBase::CButtonBase() CButton::CButton() :
state(NORMAL),
images(nullptr),
state2image(),
text(nullptr)
{ {
swappedImages = keepFrame = false;
bitmapOffset = 0;
state=NORMAL;
image = NULL;
text = NULL;
} }
CButtonBase::~CButtonBase()
{
} CButton::CButton(const CFunctionList<void()> & flist, Gfx::Point position, const std::string & animName, size_t animOffs/*=0*/, size_t imagesNum/*=4*/,
const PairOfStrings * helpStr, ui16 events/*=LCLICK|RCLICK|HOVER|KEYBOARD*/, int key/*=0*/) :
void CButtonBase::update() state(NORMAL),
images(Gfx::CManager::getAnimation(animName)),
callback(flist),
text(nullptr)
{ {
if (text) pos.x = position.x;
pos.y = position.y;
if (helpStr != nullptr)
{ {
if (state == PRESSED) helpBox = helpStr->first;
text->moveTo(Point(pos.x+pos.w/2+1, pos.y+pos.h/2+1)); status = helpStr->second;
else
text->moveTo(Point(pos.x+pos.w/2, pos.y+pos.h/2));
} }
int newPos = (int)state + bitmapOffset; if (images)
if (newPos < 0)
newPos = 0;
if (state == HIGHLIGHTED && image->getFramesCount() < 4)
newPos = image->getFramesCount()-1;
if (swappedImages)
{ {
if (newPos == 0) newPos = 1; pos.w = images->getWidth();
else if (newPos == 1) newPos = 0; pos.h = images->getHeight();
size_t i=0;
for (; i<imagesNum; ++i)
{
state2image[i] = images->getFrame(i + animOffs);
if (state2image[i] == nullptr)
{
tlog2 << "CButton warning: image " << animName << " : " << animOffs+i << " is missing\n";
state2image[i] = state2image[0]; //TODO set dummy image
}
}
for (; i<4; ++i)
{
state2image[i] = state2image[0];
}
}
else {
tlog1 << "CButton error: animation file '" << animName << "' is not loaded\n";
} }
//* if (!keepFrame) addUsedEvents(events);
//* image->setFrame(newPos); if (key != SDLK_UNKNOWN) assignedKeys.insert(key);
if (active)
redraw();
} }
void CButtonBase::addTextOverlay( const std::string &Text, EFonts font, SDL_Color color)
CButton::~CButton()
{
delete text;
}
void CButton::clickLeft(tribool down, bool previousState)
{
if (isBlocked()) return;
if (down)
{
state == PRESSED;
CCS->soundh->playSound(soundBase::button);
if (text) text->moveTo(Point(pos.x+pos.w/2+1, pos.y+pos.h/2+1));
}
else {
state = hovered ? HIGHLIGHTED : NORMAL;
if (text) text->moveTo(Point(pos.x+pos.w/2, pos.y+pos.h/2));
}
if (previousState && (down==false))
{
callback();
}
}
void CButton::clickRight(tribool down, bool previousState)
{
if (down && helpBox.size()) //there is no point to show window with nothing inside...
CRClickPopup::createAndPush(helpBox);
}
void CButton::hover(bool on)
{
if (isBlocked()) return;
state = on ? HIGHLIGHTED : NORMAL;
}
void CButton::addTextOverlay( const std::string &Text, EFonts font, SDL_Color color)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
delete text; delete text;
text = new CLabel(pos.w/2, pos.h/2, font, CENTER, color, Text); text = new CLabel(pos.w/2, pos.h/2, font, CENTER, color, Text);
update();
} }
void CButtonBase::setOffset(int newOffset) void CButton::swapImages()
{ {
if (bitmapOffset == newOffset) Gfx::CImage* tmp = state2image[0];
return; state2image[0] = state2image[1];
bitmapOffset = newOffset; state2image[1] = tmp;
update();
} }
void CButtonBase::setState(ButtonState newState)
void CButton::setState(ButtonState newState)
{ {
if (state == newState)
return;
state = newState; state = newState;
update();
} }
CButtonBase::ButtonState CButtonBase::getState()
void CButton::block(bool on)
{ {
return state; setState(on ? BLOCKED : NORMAL);
} }
bool CButtonBase::isBlocked()
void CButton::showAll()
{ {
return state == BLOCKED; state2image[state]->putAt(Gfx::Point(pos.x, pos.y));
} }
bool CButtonBase::isHighlighted() CAdventureMapButton::CAdventureMapButton()
{
return state == HIGHLIGHTED;
}
void CButtonBase::block(bool on)
{
setState(on?BLOCKED:NORMAL);
}
CAdventureMapButton::CAdventureMapButton ()
{ {
hoverable = actOnDown = borderEnabled = soundDisabled = false; hoverable = actOnDown = borderEnabled = soundDisabled = false;
borderColor.unused = 1; // represents a transparent color, used for HighlightableButton borderColor.unused = 1; // represents a transparent color, used for HighlightableButton
@ -347,7 +390,7 @@ void CAdventureMapButton::clickRight(tribool down, bool previousState)
CRClickPopup::createAndPush(helpBox); CRClickPopup::createAndPush(helpBox);
} }
void CAdventureMapButton::hover (bool on) void CAdventureMapButton::hover(bool on)
{ {
if(hoverable) if(hoverable)
{ {
@ -390,7 +433,6 @@ void CAdventureMapButton::hover (bool on)
void CAdventureMapButton::init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key) void CAdventureMapButton::init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key)
{ {
currentImage = -1;
addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD); addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD);
callback = Callback; callback = Callback;
hoverable = actOnDown = borderEnabled = soundDisabled = false; hoverable = actOnDown = borderEnabled = soundDisabled = false;
@ -405,7 +447,31 @@ void CAdventureMapButton::init(const CFunctionList<void()> &Callback, const std:
pos.y += y; pos.y += y;
if (!defName.empty()) if (!defName.empty())
{
imageNames.push_back(defName); imageNames.push_back(defName);
images = Gfx::CManager::getAnimation(defName);
if (images)
{
pos.w = images->getWidth();
pos.h = images->getHeight();
for (size_t i=0; i<4; ++i)
{
state2image[i] = images->getFrame(i);
if (state2image[i] == nullptr)
{
//tlog2 << "CAdventureMapButton warning: image " << defName << " : " << i << " is missing\n";
state2image[i] = state2image[0];
}
}
}
else {
tlog1 << "CAdventureMapButton error: animation file '" << defName << "' is not loaded\n";
}
}
if (add) if (add)
for (size_t i=0; i<add->size();i++ ) for (size_t i=0; i<add->size();i++ )
imageNames.push_back(add->at(i)); imageNames.push_back(add->at(i));
@ -414,23 +480,19 @@ void CAdventureMapButton::init(const CFunctionList<void()> &Callback, const std:
void CAdventureMapButton::setIndex(size_t index, bool playerColoredButton) void CAdventureMapButton::setIndex(size_t index, bool playerColoredButton)
{ {
if (index == currentImage || index>=imageNames.size())
return;
currentImage = index;
setImage(Gfx::CManager::getAnimation(imageNames[index]));
} }
void CAdventureMapButton::setImage(Gfx::PAnimation anim, bool playerColoredButton, int animFlags) void CAdventureMapButton::setImage(Gfx::PAnimation anim, bool playerColoredButton, int animFlags)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
image = anim; //new CAnimImage(anim, getState(), 0, 0, 0, animFlags); //* image = new CAnimImage(anim, getState(), 0, 0, 0, animFlags);
//* if (playerColoredButton) //* if (playerColoredButton)
//* image->playerColored(LOCPLINT->playerID); //* image->playerColored(LOCPLINT->playerID);
pos.w = image->getWidth(); //* pos.w = image->getWidth();
pos.h = image->getHeight(); //* pos.h = image->getHeight();
} }
void CAdventureMapButton::setPlayerColor(PlayerColor player) void CAdventureMapButton::setPlayerColor(PlayerColor player)
@ -441,8 +503,7 @@ void CAdventureMapButton::setPlayerColor(PlayerColor player)
void CAdventureMapButton::showAll() void CAdventureMapButton::showAll()
{ {
image->getFrame(0)->putAt(Gfx::Point(pos.x, pos.y)); CButton::showAll();
CIntObject::showAll(); CIntObject::showAll();
//* if (borderEnabled && borderColor.unused == 0) //* if (borderEnabled && borderColor.unused == 0)

View File

@ -3,6 +3,7 @@
#include "CIntObject.h" #include "CIntObject.h"
#include "SDL_Extensions.h" #include "SDL_Extensions.h"
#include "../FunctionList.h" #include "../FunctionList.h"
#include "../Gfx/Basic.h"
#include "../Gfx/Manager.h" #include "../Gfx/Manager.h"
struct SDL_Surface; struct SDL_Surface;
@ -77,56 +78,71 @@ public:
void showAll(); void showAll();
}; };
namespace config{struct ButtonInfo;} namespace config{ struct ButtonInfo; }
typedef std::pair<std::string,std::string> PairOfStrings;
/// Base class for buttons. /// Base class for buttons.
class CButtonBase : public CKeyShortcut class CButton : public CKeyShortcut
{ {
public: public:
enum ButtonState enum ButtonState
{ {
NORMAL=0, NORMAL = 0,
PRESSED=1, PRESSED = 1,
BLOCKED=2, BLOCKED = 2,
HIGHLIGHTED=3 HIGHLIGHTED = 3
}; };
private:
int bitmapOffset; // base offset of visible bitmap from animation protected:
ButtonState state;//current state of button from enum ButtonState state;//current state of button from enum
Gfx::PAnimation images; //images for this button
Gfx::CImage* state2image[4];
std::string helpBox; //for right-click help
std::string status;
CButton(); //c-tor
public: public:
bool swappedImages,//fix for some buttons: normal and pressed image are swapped CFunctionList<void()> callback;
keepFrame; // don't change visual representation CLabel * text; //text overlay
CButton( const CFunctionList<void()> & flist,
Gfx::Point position,
const std::string & animName,
size_t animOffs = 0,
size_t imagesNum = 4,
const PairOfStrings * helpStr = nullptr,
ui16 events = LCLICK | RCLICK | HOVER | KEYBOARD,
int key = SDLK_UNKNOWN
);
virtual ~CButton(); //d-tor
void clickRight(tribool down, bool previousState);
void clickLeft(tribool down, bool previousState);
void hover(bool on);
void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = Colors::WHITE); void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = Colors::WHITE);
void update();//to refresh button after image or text change void swapImages();
void setOffset(int newOffset);
void setState(ButtonState newState); void setState(ButtonState newState);
ButtonState getState(); ButtonState getState() const { return state; };
//just to make code clearer //just to make code clearer
void block(bool on); void block(bool on);
bool isBlocked(); bool isBlocked() const { return state == BLOCKED; };
bool isHighlighted(); bool isHighlighted() const { return state == HIGHLIGHTED; };
Gfx::PAnimation image; //image for this button void showAll();
CLabel * text;//text overlay
CButtonBase(); //c-tor
virtual ~CButtonBase(); //d-tor
}; };
/// Typical Heroes 3 button which can be inactive or active and can /// Typical Heroes 3 button which can be inactive or active and can
/// hold further information if you right-click it /// hold further information if you right-click it
class CAdventureMapButton : public CButtonBase class CAdventureMapButton : public CButton
{ {
std::vector<std::string> imageNames;//store list of images that can be used by this button std::vector<std::string> imageNames;//store list of images that can be used by this button
size_t currentImage;
public: public:
std::map<int, std::string> hoverTexts; //text for statusbar std::map<int, std::string> hoverTexts; //text for statusbar
std::string helpBox; //for right-click help
CFunctionList<void()> callback;
bool actOnDown,//runs when mouse is pressed down over it, not when up bool actOnDown,//runs when mouse is pressed down over it, not when up
hoverable,//if true, button will be highlighted when hovered hoverable,//if true, button will be highlighted when hovered
borderEnabled, borderEnabled,
@ -138,12 +154,13 @@ public:
void hover (bool on); void hover (bool on);
CAdventureMapButton(); //c-tor CAdventureMapButton(); //c-tor
CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, int key=0, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &animName, int key=0, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
CAdventureMapButton( const std::pair<std::string, std::string> &help, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, int key=0, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor CAdventureMapButton( const std::pair<std::string, std::string> &help, const CFunctionList<void()> &Callback, int x, int y, const std::string &animName, int key=0, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, config::ButtonInfo *info, int key=0);//c-tor CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, config::ButtonInfo *info, int key=0);//c-tor
void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key ); void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key );
void setOffset(int o) {};
void setIndex(size_t index, bool playerColoredButton=false); void setIndex(size_t index, bool playerColoredButton=false);
void setImage(Gfx::PAnimation anim, bool playerColoredButton=false, int animFlags=0); void setImage(Gfx::PAnimation anim, bool playerColoredButton=false, int animFlags=0);
void setPlayerColor(PlayerColor player); void setPlayerColor(PlayerColor player);

View File

@ -23,6 +23,7 @@ static GLXContext glxCtx;
#endif #endif
ui32 screenWidth = 0, screenHeight = 0; // Screen/Window size ui32 screenWidth = 0, screenHeight = 0; // Screen/Window size
// OpenGL 1.3 functions pointers // OpenGL 1.3 functions pointers
PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLACTIVETEXTUREPROC glActiveTexture;
// OpenGL 2.0 functions pointers // OpenGL 2.0 functions pointers
@ -276,7 +277,7 @@ void useNoShader()
} }
void useColorizeShader(const float cm[4][4]) void useColorizeShader(const float cm[3][3])
{ {
if (currentProgram != colorizeProgram) { if (currentProgram != colorizeProgram) {
glUseProgram(currentProgram = colorizeProgram); glUseProgram(currentProgram = colorizeProgram);
@ -293,7 +294,7 @@ void usePaletteBitmapShader(si32 x, si32 y)
} }
void usePaletteBitmapShader(si32 x, si32 y, const float cm[4][4]) void usePaletteBitmapShader(si32 x, si32 y, const float cm[3][3])
{ {
if (currentProgram != paletteBitmapProgram) { if (currentProgram != paletteBitmapProgram) {
glUseProgram(currentProgram = paletteBitmapProgram); glUseProgram(currentProgram = paletteBitmapProgram);

View File

@ -11,7 +11,7 @@ namespace GL2D
void assignTexture(ui32 slot, ui32 type, ui32 handle); void assignTexture(ui32 slot, ui32 type, ui32 handle);
void useNoShader(); void useNoShader();
void useColorizeShader(const float cm[4][4]); void useColorizeShader(const float cm[3][3]);
void usePaletteBitmapShader(si32 x, si32 y); void usePaletteBitmapShader(si32 x, si32 y);
void usePaletteBitmapShader(si32 x, si32 y, const float cm[4][4]); void usePaletteBitmapShader(si32 x, si32 y, const float cm[3][3]);
} }

View File

@ -73,11 +73,9 @@
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion> <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(VCMI_Out)</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(VCMI_Out)</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(VCMI_Out)</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(VCMI_Out)</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir> <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(VCMI_Out)</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(VCMI_Out)</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(VCMI_Out)</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(VCMI_Out)</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(Configuration)\</IntDir> <IntDir Condition="'$(Configuration)|$(Platform)'=='RD|x64'">$(Configuration)\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
@ -123,7 +121,7 @@
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;opengl32.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>LinkVerbose</ShowProgress> <ShowProgress>LinkVerbose</ShowProgress>
<OptimizeReferences>false</OptimizeReferences> <OptimizeReferences>false</OptimizeReferences>
<Profile>true</Profile> <Profile>true</Profile>
@ -138,7 +136,7 @@
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;opengl32.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<Driver>NotSet</Driver> <Driver>NotSet</Driver>
<LinkTimeCodeGeneration> <LinkTimeCodeGeneration>
</LinkTimeCodeGeneration> </LinkTimeCodeGeneration>
@ -152,7 +150,7 @@
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;opengl32.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<Driver>NotSet</Driver> <Driver>NotSet</Driver>
<LinkTimeCodeGeneration> <LinkTimeCodeGeneration>
</LinkTimeCodeGeneration> </LinkTimeCodeGeneration>
@ -238,6 +236,7 @@
<ClInclude Include="FontBase.h" /> <ClInclude Include="FontBase.h" />
<ClInclude Include="FunctionList.h" /> <ClInclude Include="FunctionList.h" />
<ClInclude Include="Gfx\Animations.h" /> <ClInclude Include="Gfx\Animations.h" />
<ClInclude Include="Gfx\Basic.h" />
<ClInclude Include="Gfx\CPaletteRGBA.h" /> <ClInclude Include="Gfx\CPaletteRGBA.h" />
<ClInclude Include="Gfx\Images.h" /> <ClInclude Include="Gfx\Images.h" />
<ClInclude Include="Gfx\FilesHeaders.h" /> <ClInclude Include="Gfx\FilesHeaders.h" />

View File

@ -94,7 +94,6 @@
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="StdInc.h" /> <ClInclude Include="StdInc.h" />
<ClInclude Include="UIFramework\CCursorHandler.h" /> <ClInclude Include="UIFramework\CCursorHandler.h" />
<ClInclude Include="UIFramework\CIntObjectClasses.h" />
<ClInclude Include="UIFramework\Geometries.h" /> <ClInclude Include="UIFramework\Geometries.h" />
<ClInclude Include="UIFramework\SDL_Extensions.h" /> <ClInclude Include="UIFramework\SDL_Extensions.h" />
<ClInclude Include="UIFramework\SDL_Pixels.h" /> <ClInclude Include="UIFramework\SDL_Pixels.h" />
@ -128,6 +127,12 @@
<ClInclude Include="UIFramework\CGuiHandler.h"> <ClInclude Include="UIFramework\CGuiHandler.h">
<Filter>UIFramework</Filter> <Filter>UIFramework</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Gfx\Basic.h">
<Filter>Gfx</Filter>
</ClInclude>
<ClInclude Include="UIFramework\CIntObjectClasses.h">
<Filter>UIFramework</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="VCMI_client.rc" /> <ResourceCompile Include="VCMI_client.rc" />

View File

@ -68,7 +68,7 @@
{ {
"special" : true, "special" : true,
"id": 133, "id": 133,
"level": 9, "level": 10,
"faction": "neutral", "faction": "neutral",
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //crystal dragon is a dragon "abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //crystal dragon is a dragon
"ability_remove": [ "FLYING" ], //Crystal Dragons do not fly "ability_remove": [ "FLYING" ], //Crystal Dragons do not fly
@ -92,7 +92,7 @@
"level": 8, "level": 8,
"faction": "neutral", "faction": "neutral",
"abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //faerie dragon is a dragon "abilities": [ [ "DRAGON_NATURE", 0, 0, 0 ], //faerie dragon is a dragon
[ "MAGIC_MIRROR", 30, 0, 0 ] [ "MAGIC_MIRROR", 30, 0, 0 ],
[ "CASTS", 5, 0, 0 ], [ "CASTS", 5, 0, 0 ],
[ "CREATURE_SPELL_POWER", 500, 0, 0], //5 spell power per dragon [ "CREATURE_SPELL_POWER", 500, 0, 0], //5 spell power per dragon
[ "SPELLCASTER", 2, "spell.magicArrow", 10 ], [ "SPELLCASTER", 2, "spell.magicArrow", 10 ],
@ -121,7 +121,7 @@
{ {
"special" : true, "special" : true,
"id": 135, "id": 135,
"level": 9, "level": 10,
"faction": "neutral", "faction": "neutral",
"abilities": [ [ "SPELL_AFTER_ATTACK", 100, 80, 0 ], //always reduce defense "abilities": [ [ "SPELL_AFTER_ATTACK", 100, 80, 0 ], //always reduce defense
[ "ACID_BREATH", 25, 0, 20 ], //20% chance to do 25 damage [ "ACID_BREATH", 25, 0, 20 ], //20% chance to do 25 damage

View File

@ -257,7 +257,7 @@ namespace CGH
std::vector<int> pom; std::vector<int> pom;
BOOST_FOREACH(const JsonNode &value, level.Vector()) BOOST_FOREACH(const JsonNode &value, level.Vector())
{ {
pom.push_back(value.Float()); pom.push_back(value.asInteger());
} }
dest.push_back(pom); dest.push_back(pom);
@ -500,11 +500,11 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector()) BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector())
{ {
commanderField.push_back (position.Float()); commanderField.push_back (position.asInteger());
} }
BOOST_FOREACH (auto position, config["commanderPositions"]["creBank"].Vector()) BOOST_FOREACH (auto position, config["commanderPositions"]["creBank"].Vector())
{ {
commanderBank.push_back (position.Float()); commanderBank.push_back (position.asInteger());
} }

View File

@ -245,7 +245,7 @@ void CArtHandler::load(bool onlyTxt)
BOOST_FOREACH(auto & node, config["artifacts"].Struct()) BOOST_FOREACH(auto & node, config["artifacts"].Struct())
{ {
int numeric = node.second["id"].Float(); int numeric = node.second["id"].asInteger();
CArtifact * art = artifacts[numeric]; CArtifact * art = artifacts[numeric];
loadArtifactJson(art, node.second); loadArtifactJson(art, node.second);
@ -274,7 +274,7 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node)
art->eventText = text["event"].String(); art->eventText = text["event"].String();
const JsonNode & graphics = node["graphics"]; const JsonNode & graphics = node["graphics"];
art->iconIndex = graphics["iconIndex"].Float(); art->iconIndex = graphics["iconIndex"].asInteger();
art->image = graphics["image"].String(); art->image = graphics["image"].String();
if (!graphics["large"].loadTo(art->large)) if (!graphics["large"].loadTo(art->large))
@ -282,7 +282,7 @@ CArtifact * CArtHandler::loadArtifact(const JsonNode & node)
art->advMapDef = graphics["map"].String(); art->advMapDef = graphics["map"].String();
art->price = node["value"].Float(); art->price = node["value"].asInteger();
{ {
auto it = artifactClassMap.find (node["class"].String()); auto it = artifactClassMap.find (node["class"].String());
if (it != artifactClassMap.end()) if (it != artifactClassMap.end())

View File

@ -656,7 +656,7 @@ void CBattleInfoCallback::battleGetStackCountOutsideHexes(bool *ac) const
RETURN_IF_NOT_BATTLE(); RETURN_IF_NOT_BATTLE();
auto accessibility = getAccesibility(); auto accessibility = getAccesibility();
for(int i = 0; i < accessibility.size(); i++) for(size_t i = 0; i < accessibility.size(); ++i)
ac[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); ac[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
} }
@ -819,7 +819,7 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
std::vector<int> affectedIds; std::vector<int> affectedIds;
int spLevel = slayerEffect->val; int spLevel = slayerEffect->val;
for(int g = 0; g < VLC->creh->creatures.size(); ++g) for(size_t g = 0; g < VLC->creh->creatures.size(); ++g)
{ {
BOOST_FOREACH(const Bonus *b, VLC->creh->creatures[g]->getBonusList()) BOOST_FOREACH(const Bonus *b, VLC->creh->creatures[g]->getBonusList())
{ {

View File

@ -84,9 +84,17 @@ void CIdentifierStorage::finalize() const
{ {
// print list of missing objects and crash // print list of missing objects and crash
// in future should try to do some cleanup (like returning all id's as 0) // in future should try to do some cleanup (like returning all id's as 0)
BOOST_FOREACH(auto object, missingObjects) if (!missingObjects.empty())
{ {
tlog1 << "Error: object " << object.first << " was not found!\n"; BOOST_FOREACH(auto object, missingObjects)
{
tlog1 << "Error: object " << object.first << " was not found!\n";
}
BOOST_FOREACH(auto object, registeredObjects)
{
tlog5 << object.first << " -> " << object.second << "\n";
}
tlog1 << "All known identifiers were dumped into log file\n";
} }
assert(missingObjects.empty()); assert(missingObjects.empty());
} }

View File

@ -6951,12 +6951,12 @@ bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMar
if(r>g) //if given resource is more expensive than wanted if(r>g) //if given resource is more expensive than wanted
{ {
val2 = ceil(r / g); val2 = (int) ceil(r / g);
val1 = 1; val1 = 1;
} }
else //if wanted resource is more expensive else //if wanted resource is more expensive
{ {
val1 = (g / r) + 0.5; val1 = (int) ((g / r) + 0.5);
val2 = 1; val2 = 1;
} }
} }

View File

@ -32,33 +32,21 @@ JsonNode::JsonNode(JsonType Type):
JsonNode::JsonNode(const char *data, size_t datasize): JsonNode::JsonNode(const char *data, size_t datasize):
type(DATA_NULL) type(DATA_NULL)
{ {
JsonParser parser(data, datasize, *this); JsonParser parser(data, datasize);
*this = parser.parse("<unknown>");
JsonValidator validator(*this); JsonValidator validator(*this);
} }
JsonNode::JsonNode(ResourceID && fileURI): JsonNode::JsonNode(ResourceID && fileURI):
type(DATA_NULL) type(DATA_NULL)
{ {
std::string filename = CResourceHandler::get()->getResourceName(fileURI); auto file = CResourceHandler::get()->loadData(fileURI);
FILE * file = fopen(filename.c_str(), "rb");
if (!file)
{
tlog1 << "Failed to open file " << filename << "\n";
perror("Last system error was ");
return;
}
fseek(file, 0, SEEK_END); JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
size_t datasize = ftell(file); *this = parser.parse(fileURI.getName());
fseek(file, 0, SEEK_SET);
char *input = new char[datasize];
datasize = fread((void*)input, 1, datasize, file);
fclose(file);
JsonParser parser(input, datasize, *this);
JsonValidator validator(*this); JsonValidator validator(*this);
delete [] input;
} }
JsonNode::JsonNode(const JsonNode &copy): JsonNode::JsonNode(const JsonNode &copy):
@ -151,9 +139,12 @@ void JsonNode::setType(JsonType Type)
} }
} }
bool JsonNode::isNull() const
int JsonNode::asInteger() const
{ {
return type == DATA_NULL; if (type == DATA_NULL) return 0;
assert(type == DATA_FLOAT);
return (int) data.Float;
} }
bool & JsonNode::Bool() bool & JsonNode::Bool()
@ -186,20 +177,16 @@ JsonMap & JsonNode::Struct()
return *data.Struct; return *data.Struct;
} }
const bool boolDefault = false; bool JsonNode::Bool() const
const bool & JsonNode::Bool() const
{ {
if (type == DATA_NULL) if (type == DATA_NULL) return false;
return boolDefault;
assert(type == DATA_BOOL); assert(type == DATA_BOOL);
return data.Bool; return data.Bool;
} }
const double floatDefault = 0; double JsonNode::Float() const
const double & JsonNode::Float() const
{ {
if (type == DATA_NULL) if (type == DATA_NULL) return 0;
return floatDefault;
assert(type == DATA_FLOAT); assert(type == DATA_FLOAT);
return data.Float; return data.Float;
} }
@ -344,12 +331,18 @@ std::ostream & operator<<(std::ostream &out, const JsonNode &node)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
JsonParser::JsonParser(const char * inputString, size_t stringSize, JsonNode &root): JsonParser::JsonParser(const char * inputString, size_t stringSize):
input(inputString, stringSize), input(inputString, stringSize),
lineCount(1), lineCount(1),
lineStart(0), lineStart(0),
pos(0) pos(0)
{ {
}
JsonNode JsonParser::parse(std::string fileName)
{
JsonNode root;
extractValue(root); extractValue(root);
extractWhitespace(false); extractWhitespace(false);
@ -357,8 +350,12 @@ JsonParser::JsonParser(const char * inputString, size_t stringSize, JsonNode &ro
if (pos < input.size()) if (pos < input.size())
error("Not all file was parsed!", true); error("Not all file was parsed!", true);
//TODO: better way to show errors (like printing file name as well) if (!errors.empty())
tlog3<<errors; {
tlog3<<"File " << fileName << " is not a valid JSON file!\n";
tlog3<<errors;
}
return root;
} }
bool JsonParser::extractSeparator() bool JsonParser::extractSeparator()
@ -889,9 +886,9 @@ JsonValidator::JsonValidator(JsonNode &root, const JsonNode &schema, bool Minimi
void JsonUtils::parseTypedBonusShort(const JsonVector& source, Bonus *dest) void JsonUtils::parseTypedBonusShort(const JsonVector& source, Bonus *dest)
{ {
dest->val = source[1].Float(); dest->val = source[1].asInteger();
resolveIdentifier(source[2],dest->subtype); resolveIdentifier(source[2],dest->subtype);
dest->additionalInfo = source[3].Float(); dest->additionalInfo = source[3].asInteger();
dest->duration = Bonus::PERMANENT; //TODO: handle flags (as integer) dest->duration = Bonus::PERMANENT; //TODO: handle flags (as integer)
dest->turnsRemain = 0; dest->turnsRemain = 0;
} }
@ -943,10 +940,10 @@ void JsonUtils::resolveIdentifier (si32 &var, const JsonNode &node, std::string
switch (value->getType()) switch (value->getType())
{ {
case JsonNode::DATA_FLOAT: case JsonNode::DATA_FLOAT:
var = value->Float(); var = value->asInteger();
break; break;
case JsonNode::DATA_STRING: case JsonNode::DATA_STRING:
VLC->modh->identifiers.requestIdentifier (value->String(), [&](si32 identifier) VLC->modh->identifiers.requestIdentifier(value->String(), [&](si32 identifier)
{ {
var = identifier; var = identifier;
}); });
@ -962,10 +959,10 @@ void JsonUtils::resolveIdentifier (const JsonNode &node, si32 &var)
switch (node.getType()) switch (node.getType())
{ {
case JsonNode::DATA_FLOAT: case JsonNode::DATA_FLOAT:
var = node.Float(); var = node.asInteger();
break; break;
case JsonNode::DATA_STRING: case JsonNode::DATA_STRING:
VLC->modh->identifiers.requestIdentifier (node.String(), [&](si32 identifier) VLC->modh->identifiers.requestIdentifier(node.String(), [&](si32 identifier)
{ {
var = identifier; var = identifier;
}); });
@ -994,7 +991,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
value = &ability["val"]; value = &ability["val"];
if (!value->isNull()) if (!value->isNull())
b->val = value->Float(); b->val = value->asInteger();
value = &ability["valueType"]; value = &ability["valueType"];
if (!value->isNull()) if (!value->isNull())
@ -1004,11 +1001,11 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
value = &ability["turns"]; value = &ability["turns"];
if (!value->isNull()) if (!value->isNull())
b->turnsRemain = value->Float(); b->turnsRemain = value->asInteger();
value = &ability["sourceID"]; value = &ability["sourceID"];
if (!value->isNull()) if (!value->isNull())
b->sid = value->Float(); b->sid = value->asInteger();
value = &ability["description"]; value = &ability["description"];
if (!value->isNull()) if (!value->isNull())

View File

@ -67,7 +67,10 @@ public:
void setType(JsonType Type); void setType(JsonType Type);
JsonType getType() const; JsonType getType() const;
bool isNull() const; bool isNull() const { return type == DATA_NULL; };
// returns int number if type == DATA_FLOAT
int asInteger() const;
//non-const accessors, node will change type on type mismatch //non-const accessors, node will change type on type mismatch
bool & Bool(); bool & Bool();
@ -77,8 +80,8 @@ public:
JsonMap & Struct(); JsonMap & Struct();
//const accessors, will cause assertion failure on type mismatch //const accessors, will cause assertion failure on type mismatch
const bool & Bool() const; bool Bool() const;
const double & Float() const; double Float() const;
const std::string & String() const; const std::string & String() const;
const JsonVector & Vector() const; const JsonVector & Vector() const;
const JsonMap & Struct() const; const JsonMap & Struct() const;
@ -118,6 +121,7 @@ public:
} }
}; };
namespace JsonUtils namespace JsonUtils
{ {
/** /**
@ -339,7 +343,10 @@ namespace JsonDetail
bool error(const std::string &message, bool warning=false); bool error(const std::string &message, bool warning=false);
public: public:
JsonParser(const char * inputString, size_t stringSize, JsonNode &root); JsonParser(const char * inputString, size_t stringSize);
/// do actual parsing. filename is name of file that will printed to console if any errors were found
JsonNode parse(std::string fileName);
}; };
//Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour: //Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour:

View File

@ -22,12 +22,12 @@ Res::ResourceSet::ResourceSet(const JsonNode & node)
{ {
reserve(GameConstants::RESOURCE_QUANTITY); reserve(GameConstants::RESOURCE_QUANTITY);
BOOST_FOREACH(std::string name, GameConstants::RESOURCE_NAMES) BOOST_FOREACH(std::string name, GameConstants::RESOURCE_NAMES)
push_back(node[name].Float()); push_back(node[name].asInteger());
} }
bool Res::ResourceSet::nonZero() const bool Res::ResourceSet::nonZero() const
{ {
for(int i = 0; i < size(); i++) for(size_t i = 0; i < size(); ++i)
if(at(i)) if(at(i))
return true; return true;
@ -36,7 +36,7 @@ bool Res::ResourceSet::nonZero() const
void Res::ResourceSet::amax(const TResourceCap &val) void Res::ResourceSet::amax(const TResourceCap &val)
{ {
for(int i = 0; i < size(); i++) for(size_t i = 0; i < size(); ++i)
::vstd::amax(at(i), val); ::vstd::amax(at(i), val);
} }

View File

@ -124,7 +124,8 @@ namespace Res
{ {
struct ResEntry struct ResEntry
{ {
TResourceCap resType, resVal; TResource resType;
TResourceCap resVal;
} cur; } cur;
const ResourceSet &rs; const ResourceSet &rs;
void advance(); void advance();