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

- New animation system:

-- New files: hch/CAnimation.h/cpp
-- Class CAnimation capable to load file partially and/or keep data in compressed state
-- Buttons now use CAnimation instead of CDefHandler

- build system regenerated to include new files
- fixed several gcc warnings
- updated README.linux
This commit is contained in:
Ivan Savenko 2010-10-18 15:08:59 +00:00
parent 6cadd47f0d
commit c10dac929d
20 changed files with 1254 additions and 352 deletions

View File

@ -13,16 +13,20 @@ And then regenerate the build system with
To compile, at least the following packages (and their development counterparts) are needed to build:
* libstdc++ devel
* boost c++ libraries v1.36+ (1.35 will not work) (www.boost.org)
* SDL and SDL-devel
* SDL_mixer and SDL_mixer-devel
* SDL_image and SDL_image-devel
* SDL_ttf and SDL_ttf-devel
* zlib and zlib-devel
* the ffmpeg libraries (libavformat and libswscale). Their name could be libavformat-devel and libswscale-devel, or ffmpeg-libs-devel or similar names.
* boost c++ libraries v1.36+ (1.35 will not work) (www.boost.org):
- filesystem
- iostreams
- system
- thread
On Ubuntu 9.04, run:
sudo apt-get install g++ libsdl1.2debian-all libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev zlib1g-dev libavformat-dev libswscale-dev libboost1.37-dev
On Ubuntu 9.04 or later, run:
sudo apt-get install g++ libsdl1.2debian-all libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-iostreams-dev libboost-system-dev libboost-thread-dev
Create a directory /YOUR_INSTALL_PATH/vcmi (such as
/usr/local/share/games/vcmi) that will contain the game data files. The /vcmi at the end is necessary.
@ -47,7 +51,7 @@ That will generate vcmiclient, vcmiserver as well as 3 .so libraries.
II. Installing Heroes of Might and Magic 3
VCMI needs an installed version of Heroes III as well as WoG on top of
it. The version of Heroes needed is (I think!) either Shadow of Death
it. The version of Heroes needed is either Shadow of Death
or Complete.
Wog can be downloaded from: http://www.maps4heroes.com/heroes3/files/allinone_358f.zip
@ -61,7 +65,7 @@ Install Heroes 3 and Wog. Then move all the installed files into
Once both programs are installed, you can install VCMI.
Download the windows VCMI release (at time of writing:
http://vcmi.antypika.aplus.pl/forum/dload.php?action=download&id=14)
http://forum.vcmi.eu/dload.php?action=download&id=18)
and extract it in a private directory. Populate /YOUR_INSTALL_PATH/vcmi:
mv sprites /YOUR_INSTALL_PATH/vcmi/Sprites

4
aclocal.m4 vendored
View File

@ -13,8 +13,8 @@
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
[m4_warning([this file was generated for autoconf 2.65.
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
[m4_warning([this file was generated for autoconf 2.67.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])

View File

@ -1,7 +1,7 @@
#include "AdventureMapButton.h"
#include "../hch/CAnimation.h"
#include "CAdvmapInterface.h"
#include "SDL_Extensions.h"
#include "../hch/CDefHandler.h"
#include "CGameInfo.h"
#include "../hch/CLodHandler.h"
#include "../hch/CGeneralTextHandler.h"
@ -14,7 +14,7 @@
#include "CMessage.h"
/*
* AdevntureMapButton.cpp, part of VCMI engine
* AdventureMapButton.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
@ -41,19 +41,19 @@ CButtonBase::~CButtonBase()
delete text;
if(notFreeButton)
return;
for(int i =0; i<imgs.size();i++)
for(int j=0;j<imgs[i].size();j++)
SDL_FreeSurface(imgs[i][j]);
for (size_t i = 0; i<imgs.size(); i++)
delete imgs[i];
imgs.clear();
}
void CButtonBase::show(SDL_Surface * to)
{
int img = std::min(state+bitmapOffset,int(imgs[curimg].size()-1));
int img = std::min(state+bitmapOffset,int(imgs[curimg]->size()-1));
img = std::max(0, img);
if (abs)
{
blitAt(imgs[curimg][img],pos.x,pos.y,to);
blitAt(imgs[curimg]->image(img),pos.x,pos.y,to);
if(text)
{//using "state" instead of "state == 1" screwed up hoverable buttons with text
CSDL_Ext::printAt(text->text, text->x + pos.x + (state == 1), text->y + pos.y + (state == 1), text->font, text->color, to);
@ -61,7 +61,7 @@ void CButtonBase::show(SDL_Surface * to)
}
else
{
blitAt(imgs[curimg][img],pos.x+ourObj->pos.x,pos.y+ourObj->pos.y,to);
blitAt(imgs[curimg]->image(img),pos.x+ourObj->pos.x,pos.y+ourObj->pos.y,to);
}
}
@ -221,28 +221,15 @@ void AdventureMapButton::init(const CFunctionList<void()> &Callback, const std::
setDef(defName, playerColoredButton);
if (add && add->size())
{
imgs.resize(imgs.size()+add->size());
for (size_t i=0; i<add->size();i++)
{
CDefHandler *temp = CDefHandler::giveDef((*add)[i]);
temp->notFreeImgs = true;
for (size_t j=0;j<temp->ourImages.size();j++)
{
imgs[i+1].push_back(temp->ourImages[j].bitmap);
if(playerColoredButton)
{
graphics->blueToPlayersAdv(imgs[1+i][j],LOCPLINT->playerID);
}
}
delete temp;
}
//delete add;
}
setDef((*add)[i], playerColoredButton);
if (playerColoredButton)
setPlayerColor(LOCPLINT->playerID);
pos.x += x;
pos.y += y;
pos.w = imgs[curimg][0]->w;
pos.h = imgs[curimg][0]->h -1;
pos.w = imgs[curimg]->image(0)->w;
pos.h = imgs[curimg]->image(0)->h -1;
}
void AdventureMapButton::block( ui8 on )
@ -257,30 +244,22 @@ void AdventureMapButton::setDef(const std::string & defName, bool playerColoredB
{
if (reset)
{
for (size_t i=0;i<imgs[0].size();i++)
SDL_FreeSurface(imgs[0][i]);
imgs[0].clear();
for (size_t i=0; i<imgs.size(); i++)
delete imgs[i];
imgs.clear();
}
CDefHandler * temp = CDefHandler::giveDef(defName);
temp->notFreeImgs = true;
for (size_t i=0;i<temp->ourImages.size();i++)
{
imgs.resize(1);
imgs[0].push_back(temp->ourImages[i].bitmap);
if(playerColoredButton)
{
graphics->blueToPlayersAdv(imgs[curimg][i],LOCPLINT->playerID);
}
}
delete temp;
imgs.push_back(new CAnimation(defName));
imgs.back()->load();
}
void AdventureMapButton::setPlayerColor(int player)
{
for(int i =0; i<imgs.size();i++)
for(int j=0;j<imgs[i].size();j++)
graphics->blueToPlayersAdv(imgs[i][j],player);
for(size_t i =0; i<imgs.size();i++)
for(size_t j=0;j<imgs[i]->size();j++)
{
graphics->blueToPlayersAdv(imgs[i]->image(j),player);
}
}
void CHighlightableButton::select(bool on)
@ -364,7 +343,7 @@ void CHighlightableButtonsGroup::addButton(const std::map<int,std::string> &tool
}
CHighlightableButtonsGroup::CHighlightableButtonsGroup(const CFunctionList2<void(int)> &OnChange, bool musicLikeButtons)
: musicLike(musicLikeButtons), onChange(OnChange)
: onChange(OnChange), musicLike(musicLikeButtons)
{}
CHighlightableButtonsGroup::~CHighlightableButtonsGroup()
@ -559,7 +538,7 @@ void CSlider::clickLeft(tribool down, bool previousState)
CSlider::~CSlider()
{
delete imgs;
}
CSlider::CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int Capacity, int Amount, int Value, bool Horizontal, int style)
@ -609,19 +588,23 @@ CSlider::CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int
if(style == 0)
{
if (horizontal)
imgs = CDefHandler::giveDefEss("IGPCRDIV.DEF");
else
imgs = CDefHandler::giveDefEss("OVBUTN2.DEF");
left->imgs.resize(1); right->imgs.resize(1); slider->imgs.resize(1);
left->imgs[0].push_back(imgs->ourImages[0].bitmap); left->imgs[0].push_back(imgs->ourImages[1].bitmap);
right->imgs[0].push_back(imgs->ourImages[2].bitmap); right->imgs[0].push_back(imgs->ourImages[3].bitmap);
slider->imgs[0].push_back(imgs->ourImages[4].bitmap);
left->notFreeButton = right->notFreeButton = slider->notFreeButton = true;
CAnimation * pics = new CAnimation(horizontal?"IGPCRDIV.DEF":"OVBUTN2.DEF");
pics->load();
left->imgs.push_back(new CAnimation());
right->imgs.push_back(new CAnimation());
slider->imgs.push_back(new CAnimation());
left->imgs.back()->add(pics->image(0), true);
left->imgs.back()->add(pics->image(1), true);
right->imgs.back()->add(pics->image(2), true);
right->imgs.back()->add(pics->image(3), true);
slider->imgs.back()->add(pics->image(4), true);
delete pics;
}
else
{
imgs = NULL;
left->setDef(horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", false);
right->setDef(horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", false);
slider->setDef("SCNRBSL.DEF", false);

View File

@ -17,7 +17,7 @@
extern SDL_Color tytulowy, tlo, zwykly ;
class CDefEssential;
class CAnimation;
namespace config{struct ButtonInfo;}
@ -41,7 +41,7 @@ public:
bool notFreeButton; //TODO: comment me
CIntObject * ourObj; // "owner"
int state; //TODO: comment me
std::vector< std::vector<SDL_Surface*> > imgs; //images for this button
std::vector< CAnimation * > imgs; //images for this button
int curimg; //curently displayed image from imgs
virtual void show(SDL_Surface * to);
virtual void showAll(SDL_Surface * to);
@ -129,8 +129,6 @@ public:
bool wheelScrolling;
bool keyScrolling;
CDefEssential *imgs ;
boost::function<void(int)> moved;
void redrawSlider();

View File

@ -4,6 +4,7 @@
#include "SDL_Extensions.h"
#include "CAdvmapInterface.h"
#include "AdventureMapButton.h"
#include "../hch/CAnimation.h"
#include "../hch/CObjectHandler.h"
#include "../hch/CHeroHandler.h"
#include "../hch/CDefHandler.h"
@ -3914,9 +3915,9 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt
animSpeeds->onChange = boost::bind(&CBattleInterface::setAnimSpeed, owner, _1);
setToDefault = new AdventureMapButton (CGI->generaltexth->zelp[392].first, CGI->generaltexth->zelp[392].second, boost::bind(&CBattleOptionsWindow::bDefaultf,this), 405, 443, "codefaul.def");
std::swap(setToDefault->imgs[0][0], setToDefault->imgs[0][1]);
setToDefault->imgs[0]->fixButtonPos();
exit = new AdventureMapButton (CGI->generaltexth->zelp[393].first, CGI->generaltexth->zelp[393].second, boost::bind(&CBattleOptionsWindow::bExitf,this), 516, 443, "soretrn.def",SDLK_RETURN);
std::swap(exit->imgs[0][0], exit->imgs[0][1]);
exit->imgs[0]->fixButtonPos();
//printing texts to background
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[392], 242, 32, FONT_BIG, tytulowy, background); //window title

View File

@ -1138,9 +1138,8 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
if(down)
{
CCastleInterface * ci=LOCPLINT->castleInt;
const CGTownInstance * town = ci->town;
std::set<si32> bld = ci->town->builtBuildings;
int summ=0, cnt=0;
int summ=0;
std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number
boost::algorithm::replace_first(descr,"%s",CGI->creh->creatures[crid]->nameSing);
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(ci->town->creatureGrowth(level)));
@ -1174,7 +1173,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
summ+=AddToString(CGI->buildh->buildings[ci->town->subID][24]->Name()+" %+d",descr,
CGI->creh->creatures[crid]->hordeGrowth);
cnt = 0;
int cnt = 0;
std::vector< const CGDwelling * > myDwellings = LOCPLINT->cb->getMyDwellings();
for (std::vector<const CGDwelling*>::const_iterator it = myDwellings.begin(); it != myDwellings.end(); ++it)

View File

@ -2,14 +2,18 @@
#include "CConfigHandler.h"
#include <boost/bind.hpp>
#include <boost/function.hpp>
#if BOOST_VERSION >= 103800
#include <boost/spirit/include/classic.hpp>
#else
#include <boost/spirit.hpp>
#endif
#include <boost/version.hpp>
#include <fstream>
using namespace config;
#if BOOST_VERSION >= 103800
#include <boost/spirit/include/classic.hpp>
using namespace boost::spirit::classic;
#else
#include <boost/spirit.hpp>
using namespace boost::spirit;
#endif
using namespace phoenix;
/*

View File

@ -2,6 +2,7 @@
#include "CMessage.h"
#include "SDL_ttf.h"
#include "../hch/CDefHandler.h"
#include "../hch/CAnimation.h"
#include "CGameInfo.h"
#include "SDL_Extensions.h"
#include "../hch/CLodHandler.h"
@ -427,7 +428,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
// Compute total width of buttons
bw = 20*(ret->buttons.size()-1); // space between all buttons
for(size_t i=0; i<ret->buttons.size(); i++) //and add buttons width
bw+=ret->buttons[i]->imgs[0][0]->w;
bw+=ret->buttons[i]->imgs[0]->image(0)->w;
winSize.second += 20 + //before button
ok->ourImages[0].bitmap->h; //button
}
@ -464,13 +465,13 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
{
// Position the buttons at the bottom of the window
bw = (ret->bitmap->w/2) - (bw/2);
curh = ret->bitmap->h - SIDE_MARGIN - ret->buttons[0]->imgs[0][0]->h;
curh = ret->bitmap->h - SIDE_MARGIN - ret->buttons[0]->imgs[0]->image(0)->h;
for(size_t i=0; i<ret->buttons.size(); i++)
{
ret->buttons[i]->pos.x = bw + ret->pos.x;
ret->buttons[i]->pos.y = curh + ret->pos.y;
bw += ret->buttons[i]->imgs[0][0]->w + 20;
bw += ret->buttons[i]->imgs[0]->image(0)->w + 20;
}
}
for(size_t i=0; i<ret->components.size(); i++)

View File

@ -9,6 +9,7 @@
#include "SDL_Extensions.h"
#include "CGameInfo.h"
#include "CCursorHandler.h"
#include "../hch/CAnimation.h"
#include "../hch/CDefHandler.h"
#include "../hch/CDefObjInfoHandler.h"
#include "../hch/CGeneralTextHandler.h"
@ -798,7 +799,7 @@ void SelectionTab::parseCampaigns( std::vector<FileInfo> & files )
}
SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(CMapInfo *)> &OnSelect, bool MultiPlayer)
:onSelect(OnSelect), bg(NULL)
:bg(NULL), onSelect(OnSelect)
{
OBJ_CONSTRUCTION;
selectionPos = 0;
@ -1239,7 +1240,7 @@ CChatBox::CChatBox(const Rect &rect)
}
InfoCard::InfoCard( CMenuScreen::EState Type, bool network )
: difficulty(NULL), sizes(NULL), sFlags(NULL), bg(NULL), chatOn(false), chat(NULL)
: bg(NULL), chatOn(false), chat(NULL), difficulty(NULL), sizes(NULL), sFlags(NULL)
{
OBJ_CONSTRUCTION;
pos.x += 393;
@ -2333,8 +2334,8 @@ void CHotSeatPlayers::enterSelectionScreen()
}
CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign )
: ourCampaign(_ourCampaign), highlightedRegion(NULL), ourHeader(NULL), bonuses(NULL),
diffLb(NULL), diffRb(NULL)
: highlightedRegion(NULL), ourCampaign(_ourCampaign), ourHeader(NULL),
diffLb(NULL), diffRb(NULL), bonuses(NULL)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
static const std::string bgNames [] = {"E1_BG.BMP", "G2_BG.BMP", "E2_BG.BMP", "G1_BG.BMP", "G3_BG.BMP", "N1_BG.BMP",
@ -2765,9 +2766,9 @@ void CBonusSelection::updateBonusSelection()
blitAt(twcp->ourImages[1].bitmap, 0, 0, selected);
//moving surfaces into button
bonuses->buttons.back()->imgs[0].clear();
bonuses->buttons.back()->imgs[0].push_back(notSelected);
bonuses->buttons.back()->imgs[0].push_back(selected);
bonuses->buttons.back()->imgs[0]->unload();
bonuses->buttons.back()->imgs[0]->add(notSelected);
bonuses->buttons.back()->imgs[0]->add(selected);
//cleaning
delete de;

View File

@ -15,6 +15,7 @@
#include "CConfigHandler.h"
#include "CCreatureAnimation.h"
#include "Graphics.h"
#include "../hch/CAnimation.h"
#include "../hch/CArtHandler.h"
#include "../hch/CBuildingHandler.h"
#include "../hch/CGeneralTextHandler.h"
@ -3868,19 +3869,19 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
// std::swap(save->imgs[0][0], load->imgs[0][1]);
save = new AdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second, boost::bind(&CSystemOptionsWindow::bsavef, this), pos.x+357, pos.y+298, "SOSAVE.DEF", SDLK_s);
std::swap(save->imgs[0][0], save->imgs[0][1]);
save->imgs[0]->fixButtonPos();
// restart = new AdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+346, pos.y+357, "SORSTRT", SDLK_r);
// std::swap(save->imgs[0][0], restart->imgs[0][1]);
mainMenu = new AdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+357, pos.y+357, "SOMAIN.DEF", SDLK_m);
std::swap(mainMenu->imgs[0][0], mainMenu->imgs[0][1]);
mainMenu->imgs[0]->fixButtonPos();
quitGame = new AdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second, boost::bind(&CSystemOptionsWindow::bquitf, this), pos.x+246, pos.y+415, "soquit.def", SDLK_q);
std::swap(quitGame->imgs[0][0], quitGame->imgs[0][1]);
quitGame->imgs[0]->fixButtonPos();
backToMap = new AdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second, boost::bind(&CSystemOptionsWindow::breturnf, this), pos.x+357, pos.y+415, "soretrn.def", SDLK_RETURN);
std::swap(backToMap->imgs[0][0], backToMap->imgs[0][1]);
backToMap->imgs[0]->fixButtonPos();
backToMap->assignedKeys.insert(SDLK_ESCAPE);
heroMoveSpeed = new CHighlightableButtonsGroup(0);

View File

@ -13,7 +13,8 @@ vcmiclient_SOURCES = \
../CThreadHelper.h \
../StartInfo.h \
../global.h \
../hch/CAmbarCendamo.h \
../hch/CAnimation.h \
../hch/CAnimation.cpp \
../hch/CBuildingHandler.h \
../hch/CDefHandler.cpp \
../hch/CDefHandler.h \

View File

@ -59,6 +59,7 @@ PROGRAMS = $(bin_PROGRAMS)
am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \
vcmiclient-CGameInterface.$(OBJEXT) \
vcmiclient-CThreadHelper.$(OBJEXT) \
vcmiclient-CAnimation.$(OBJEXT) \
vcmiclient-CDefHandler.$(OBJEXT) \
vcmiclient-CMusicHandler.$(OBJEXT) \
vcmiclient-CSndHandler.$(OBJEXT) \
@ -280,7 +281,8 @@ vcmiclient_SOURCES = \
../CThreadHelper.h \
../StartInfo.h \
../global.h \
../hch/CAmbarCendamo.h \
../hch/CAnimation.h \
../hch/CAnimation.cpp \
../hch/CBuildingHandler.h \
../hch/CDefHandler.cpp \
../hch/CDefHandler.h \
@ -437,6 +439,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-AdventureMapButton.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-CAdvmapInterface.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-CAnimation.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-CBattleInterface.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-CBitmapHandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcmiclient-CCallback.Po@am__quote@
@ -539,6 +542,22 @@ vcmiclient-CThreadHelper.obj: ../CThreadHelper.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CThreadHelper.obj `if test -f '../CThreadHelper.cpp'; then $(CYGPATH_W) '../CThreadHelper.cpp'; else $(CYGPATH_W) '$(srcdir)/../CThreadHelper.cpp'; fi`
vcmiclient-CAnimation.o: ../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
vcmiclient-CAnimation.obj: ../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
vcmiclient-CDefHandler.o: ../hch/CDefHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CDefHandler.o -MD -MP -MF $(DEPDIR)/vcmiclient-CDefHandler.Tpo -c -o vcmiclient-CDefHandler.o `test -f '../hch/CDefHandler.cpp' || echo '$(srcdir)/'`../hch/CDefHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CDefHandler.Tpo $(DEPDIR)/vcmiclient-CDefHandler.Po

View File

@ -61,9 +61,9 @@ STRONG_INLINE void ColorPutter<bpp, incrementPtr>::PutColorAlphaSwitch(Uint8 *&p
template<int bpp, int incrementPtr>
STRONG_INLINE void ColorPutter<bpp, incrementPtr>::PutColor(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B, const Uint8 & A)
{
PutColor(ptr, (((Uint32)ptr[2]-(Uint32)R)*(Uint32)A) >> 8 + (Uint32)R,
(((Uint32)ptr[1]-(Uint32)G)*(Uint32)A) >> 8 + (Uint32)G,
(((Uint32)ptr[0]-(Uint32)B)*(Uint32)A) >> 8 + (Uint32)B);
PutColor(ptr, (((Uint32)ptr[2]-(Uint32)R)*(Uint32)A) >> (8 + (Uint32)R),
(((Uint32)ptr[1]-(Uint32)G)*(Uint32)A) >> (8 + (Uint32)G),
(((Uint32)ptr[0]-(Uint32)B)*(Uint32)A) >> (8 + (Uint32)B));
}

478
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ if test "x$GXX" = "xyes" -a "x$enable_debug" = "xyes" ; then
fi
if test "x$GXX" = "xyes" ; then
CXXFLAGS="$CXXFLAGS -Wall -Wno-switch-enum -Wno-sign-compare -Wcast-align -Wpointer-arith"
CXXFLAGS="$CXXFLAGS -Wall -Wno-switch -Wno-sign-compare -Wcast-align -Wpointer-arith"
fi
CXXFLAGS="$CXXFLAGS -DDATA_DIR=\\\"\$(pkgdatadir)\\\" -DBIN_DIR=\\\"\$(bindir)\\\" -DLIB_DIR=\\\"\$(pkglibdir)\\\""

689
hch/CAnimation.cpp Normal file
View File

@ -0,0 +1,689 @@
#include <iostream>
#include <sstream>
#include <boost/foreach.hpp>
#include "SDL.h"
#include "SDL_image.h"
#include "../client/CBitmapHandler.h"
#include "CAnimation.h"
#include "CLodHandler.h"
/*
* CAnimation.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
extern DLL_EXPORT CLodHandler *spriteh;
/*************************************************************************
* DefFile, class used for def loading *
*************************************************************************/
bool CDefFile::haveFrame(size_t frame, size_t group) const
{
if (offset.size() > group)
if (offset[group].size() > frame)
return true;
return false;
}
SDL_Surface * CDefFile::loadFrame(size_t frame, size_t group) const
{
if (haveFrame(frame, group))
return loadFrame(( unsigned char * )data+offset[group][frame], colors);
return NULL;
}
SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette * palette)
{
SDL_Surface * ret=NULL;
unsigned int BaseOffset,
SpriteWidth, SpriteHeight, //format of sprite
TotalRowLength, // length of read segment
add, FullHeight,FullWidth,
RowAdd,
prSize,
defType2;
int LeftMargin, RightMargin, TopMargin, BottomMargin;
unsigned char SegmentType;
BaseOffset = 0;
SSpriteDef sd = * reinterpret_cast<const SSpriteDef *>(FDef + BaseOffset);
prSize = SDL_SwapLE32(sd.prSize);
defType2 = SDL_SwapLE32(sd.defType2);
FullWidth = SDL_SwapLE32(sd.FullWidth);
FullHeight = SDL_SwapLE32(sd.FullHeight);
SpriteWidth = SDL_SwapLE32(sd.SpriteWidth);
SpriteHeight = SDL_SwapLE32(sd.SpriteHeight);
LeftMargin = SDL_SwapLE32(sd.LeftMargin);
TopMargin = SDL_SwapLE32(sd.TopMargin);
RightMargin = FullWidth - SpriteWidth - LeftMargin;
BottomMargin = FullHeight - SpriteHeight - TopMargin;
//if(LeftMargin + RightMargin < 0)
// SpriteWidth += LeftMargin + RightMargin; //ugly construction... TODO: check how to do it nicer
if (LeftMargin<0)
SpriteWidth+=LeftMargin;
if (RightMargin<0)
SpriteWidth+=RightMargin;
// Note: this looks bogus because we allocate only FullWidth, not FullWidth+add
add = 4 - FullWidth%4;
if (add==4)
add=0;
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0);
//int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str()));
BaseOffset += sizeof(SSpriteDef);
int BaseOffsetor = BaseOffset;
for (int i=0; i<256; ++i)
{
SDL_Color pr;
pr.r = palette[i].R;
pr.g = palette[i].G;
pr.b = palette[i].B;
pr.unused = palette[i].F;
(*(ret->format->palette->colors+i))=pr;
}
int ftcp=0;
// If there's a margin anywhere, just blank out the whole surface.
if (TopMargin > 0 || BottomMargin > 0 || LeftMargin > 0 || RightMargin > 0)
{
memset( reinterpret_cast<char*>(ret->pixels), 0, FullHeight*FullWidth);
}
// Skip top margin
if (TopMargin > 0)
ftcp += TopMargin*(FullWidth+add);
switch (defType2)
{
case 0:
{
for (unsigned int i=0; i<SpriteHeight; i++)
{
if (LeftMargin>0)
ftcp += LeftMargin;
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, &FDef[BaseOffset], SpriteWidth);
ftcp += SpriteWidth;
BaseOffset += SpriteWidth;
if (RightMargin>0)
ftcp += RightMargin;
}
}
break;
case 1:
{
const unsigned int * RWEntriesLoc = reinterpret_cast<const unsigned int *>(FDef+BaseOffset);
BaseOffset += sizeof(int) * SpriteHeight;
for (unsigned int i=0; i<SpriteHeight; i++)
{
BaseOffset=BaseOffsetor + SDL_SwapLE32(read_unaligned_u32(RWEntriesLoc + i));
if (LeftMargin>0)
ftcp += LeftMargin;
TotalRowLength=0;
do
{
unsigned int SegmentLength;
SegmentType=FDef[BaseOffset++];
SegmentLength=FDef[BaseOffset++] + 1;
if (SegmentType==0xFF)
{
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, FDef + BaseOffset, SegmentLength);
BaseOffset+=SegmentLength;
}
else
{
memset(reinterpret_cast<char*>(ret->pixels)+ftcp, SegmentType, SegmentLength);
}
ftcp += SegmentLength;
TotalRowLength += SegmentLength;
}
while (TotalRowLength<SpriteWidth);
RowAdd=SpriteWidth-TotalRowLength;
if (RightMargin>0)
ftcp += RightMargin;
if (add>0)
ftcp += add+RowAdd;
}
}
break;
case 2:
{
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor));
for (unsigned int i=0; i<SpriteHeight; i++)
{
//BaseOffset = BaseOffsetor+RWEntries[i];
if (LeftMargin>0)
ftcp += LeftMargin;
TotalRowLength=0;
do
{
SegmentType=FDef[BaseOffset++];
unsigned char code = SegmentType / 32;
unsigned char value = (SegmentType & 31) + 1;
if (code==7)
{
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, &FDef[BaseOffset], value);
ftcp += value;
BaseOffset += value;
}
else
{
memset(reinterpret_cast<char*>(ret->pixels)+ftcp, code, value);
ftcp += value;
}
TotalRowLength+=value;
}
while (TotalRowLength<SpriteWidth);
if (RightMargin>0)
ftcp += RightMargin;
RowAdd=SpriteWidth-TotalRowLength;
if (add>0)
ftcp += add+RowAdd;
}
}
break;
case 3:
{
for (unsigned int i=0; i<SpriteHeight; i++)
{
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor+i*2*(SpriteWidth/32)));
if (LeftMargin>0)
ftcp += LeftMargin;
TotalRowLength=0;
do
{
SegmentType=FDef[BaseOffset++];
unsigned char code = SegmentType / 32;
unsigned char value = (SegmentType & 31) + 1;
int len = std::min<unsigned int>(value, SpriteWidth - TotalRowLength) - std::max(0, -LeftMargin);
amax(len, 0);
if (code==7)
{
memcpy((ui8*)ret->pixels + ftcp, FDef + BaseOffset, len);
ftcp += len;
BaseOffset += len;
}
else
{
memset((ui8*)ret->pixels + ftcp, code, len);
ftcp += len;
}
TotalRowLength+=( LeftMargin>=0 ? value : value+LeftMargin );
}
while (TotalRowLength<SpriteWidth);
if (RightMargin>0)
ftcp += RightMargin;
RowAdd=SpriteWidth-TotalRowLength;
if (add>0)
ftcp += add+RowAdd;
}
}
break;
default:
throw std::string("Unknown sprite format.");
break;
}
SDL_Color ttcol = ret->format->palette->colors[0];
Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
return ret;
};
BMPPalette * CDefFile::getPalette()
{
BMPPalette * ret = new BMPPalette[256];
memcpy(ret, colors, sizeof(BMPPalette)*256);
return ret;
}
CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL)
{
data = spriteh->giveFile(Name, &datasize);
if (!data)
{
tlog0<<"Error: file "<< Name <<" not found\n";
return;
}
colors = new BMPPalette[256];
int it = 0;
//int type = readNormalNr(data, it); it+=4;
//int width = readNormalNr(data, it); it+=4;//not used
//int height = readNormalNr(data, it); it+=4;
it+=12;
unsigned int totalBlocks = readNormalNr(data, it);
it+=4;
for (unsigned int i=0; i<256; i++)
{
colors[i].R = data[it++];
colors[i].G = data[it++];
colors[i].B = data[it++];
colors[i].F = 0;
}
offset.resize(totalBlocks);
offList.insert(datasize);
for (unsigned int i=0; i<totalBlocks; i++)
{
it+=4;
unsigned int totalEntries = readNormalNr(data, it);
it+=12;
//13 bytes for name of every frame in this block - not used, skipping
it+= 13 * totalEntries;
for (unsigned int j=0; j<totalEntries; j++)
{
size_t currOffset = readNormalNr(data, it);
offset[i].push_back(currOffset);
offList.insert(currOffset);
it += 4;
}
}
}
unsigned char * CDefFile::getFrame(size_t frame, size_t group) const
{
if (offset.size() > group)
{
if (offset[group].size() > frame)
{
size_t offs = offset[group][frame];
std::set<size_t>::iterator it = offList.find(offs);
if (it == offList.end() || ++it == offList.end())
tlog0<<"Error: offset not found!\n";
size_t size = *it - offs;
unsigned char * ret = new unsigned char[size];
memcpy(ret, data+offs, size);
return ret;
}
}
return NULL;
}
CDefFile::~CDefFile()
{
delete[] data;
delete[] colors;
}
bool CDefFile::loaded() const
{
return data != NULL;
}
/*************************************************************************
* CAnimation for animations handling, can load part of file if needed *
*************************************************************************/
CAnimation::AnimEntry::AnimEntry():
surf(NULL),
source(0),
refCount(0),
data(NULL),
dataSize(0)
{
}
bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
{
if (groupSize(group) <= frame)
return false;
AnimEntry &e = entries[group][frame];
if (e.surf || e.data)
{
e.refCount++;
return true;
}
if (e.source & 6)//load frame with SDL_Image
{
int size;
unsigned char * pic = NULL;
std::ostringstream str;
if ( e.source & 2 )
str << name << '#' << (group+1) << '#' << (frame+1); // file#12#34.*
else
str << name << '#' << (frame+1);//file#34.*
pic = spriteh->giveFile(str.str(), &size);
if (pic)
{
if (compressed)
{
e.data = pic;
e.dataSize = size;
}
else
{
e.surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1);
delete pic;
}
}
}
else if (file && e.source & 1)//try to get image from def
{
if (compressed)
e.data = file->getFrame(frame, group);
else
e.surf = file->loadFrame(frame, group);
}
if (!(e.surf || e.data))
return false;//failed to load
e.refCount++;
return true;
}
bool CAnimation::unloadFrame(size_t frame, size_t group)
{
if (groupSize(group) > frame && entries[group][frame].refCount)
{
AnimEntry &e = entries[group][frame];
if (--e.refCount)//not last ref
return true;
SDL_FreeSurface(e.surf);
delete e.data;
e.surf = NULL;
e.data = NULL;
return true;
}
return false;
}
void CAnimation::decompress(AnimEntry &entry)
{
if (entry.source & 6)//load frame with SDL_Image
entry.surf = IMG_Load_RW( SDL_RWFromMem((void*)entry.data, entry.dataSize), 1);
else if (entry.source & 1)
entry.surf = CDefFile::loadFrame(entry.data, defPalette);
}
void CAnimation::init(CDefFile * file)
{
if (compressed)
defPalette = file->getPalette();
for (size_t group = 0; ; group++)
{
std::vector<AnimEntry> toAdd;
for (size_t frame = 0; ; frame++)
{
unsigned char res=0;
{
std::ostringstream str;
str << name << '#' << (group+1) << '#' << (frame+1); // format: file#12#34.*
if (spriteh->haveFile(str.str()))
res |= 2;
}
if (group == 0)
{
std::ostringstream str;
str << name << '#' << (frame+1);// format: file#34.*
if ( spriteh->haveFile(str.str()))
res |=4;
}
if (file)//we have def too. try to get image from def
{
if (file->haveFrame(frame, group))
res |=1;
}
if (res)
{
toAdd.push_back(AnimEntry());
toAdd.back().source = res;
}
else
break;
}
if (!toAdd.empty())
{
entries.push_back(toAdd);
break;
}
}
}
CDefFile * CAnimation::getFile() const
{
CDefFile * file = new CDefFile(name);
if (!file->loaded())
{
delete file;
return NULL;
}
return file;
}
void CAnimation::printError(size_t frame, size_t group, std::string type) const
{
tlog0 << type <<" error: Request for frame not present in CAnimation!\n"
<<"\tFile name: "<<name<<" Group: "<<group<<" Frame: "<<frame<<"\n";
}
CAnimation::CAnimation(std::string Name, bool Compressed):
name(Name),
compressed(Compressed),
defPalette(NULL)
{
std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))toupper);
int dotPos = name.find_last_of('.');
if ( dotPos != -1 )
name.erase(dotPos);
CDefFile * file = getFile();
init(file);
delete file;
}
CAnimation::CAnimation():
name(""),
compressed(false),
defPalette(NULL)
{
}
CAnimation::~CAnimation()
{
delete defPalette;
for (size_t i = 0; i < entries.size(); i++)
for (size_t j = 0; j < entries.at(i).size(); j++)
{
delete entries[i][j].data;
if (entries[i][j].surf)
SDL_FreeSurface(entries[i][j].surf);
}
}
void CAnimation::add(SDL_Surface * surf, bool shared, size_t group)
{
if (!surf)
return;
if (entries.size() <= group)
entries.resize(group+1);
if (shared)
surf->refcount++;
entries[group].push_back(AnimEntry());
entries[group].back().refCount = 1;
entries[group].back().surf = surf;
}
void CAnimation::purgeCompressed()
{
for (size_t group; group < entries.size(); group++)
for (size_t frame; frame < entries[group].size(); frame++)
if (entries[group][frame].surf)
SDL_FreeSurface(entries[group][frame].surf);
}
SDL_Surface * CAnimation::image(size_t frame)
{
size_t group=0;
for (; group<entries.size() && frame > entries[group].size(); group++)
frame -= entries[group].size();
return image(frame, group);
}
SDL_Surface * CAnimation::image(size_t frame, size_t group)
{
if ( groupSize(group) > frame )
{
AnimEntry &e = entries[group][frame];
if (!e.surf && e.data)
decompress(e);
return e.surf;
}
printError(frame, group, "GetImage");
return NULL;
}
void CAnimation::load()
{
CDefFile * file = getFile();
for (size_t group = 0; group<entries.size(); group++)
for (size_t frame = 0; frame<entries[group].size(); frame++)
loadFrame(file, frame, group);
delete file;
}
void CAnimation::unload()
{
for (size_t group = 0; group<entries.size(); group++)
for (size_t frame = 0; frame<entries[group].size(); frame++)
unloadFrame(frame, group);
}
void CAnimation::loadGroup(size_t group)
{
CDefFile * file = getFile();
for (size_t frame = 0; frame<entries[group].size(); frame++)
loadFrame(file, frame, group);
}
void CAnimation::unloadGroup(size_t group)
{
for (size_t frame = 0; frame<entries[group].size(); frame++)
unloadFrame(frame, group);
}
void CAnimation::load(size_t frame, size_t group)
{
CDefFile * file = getFile();
loadFrame(file, frame, group);
delete file;
}
void CAnimation::unload(size_t frame, size_t group)
{
unloadFrame(frame, group);
}
void CAnimation::load(std::vector <std::pair <size_t, size_t> > frames)
{
CDefFile * file = getFile();
for (size_t i=0; i<frames.size(); i++)
loadFrame(file, frames[i].second, frames[i].first);
delete file;
}
void CAnimation::unload(std::vector <std::pair <size_t, size_t> > frames)
{
for (size_t i=0; i<frames.size(); i++)
unloadFrame(frames[i].second, frames[i].first);
}
void CAnimation::fixButtonPos()
{
if ( groupSize(0) > 1 )
std::swap(entries[0][1].surf, entries[0][0].surf);
}
size_t CAnimation::groupSize(size_t group) const
{
if (entries.size() > group)
return entries[group].size();
return 0;
}
size_t CAnimation::size() const
{
size_t ret=0;
for (size_t i=0; i<entries.size(); i++)
{
ret += entries[i].size();
}
return ret;
}

177
hch/CAnimation.h Normal file
View File

@ -0,0 +1,177 @@
#ifndef __CANIMATION_H__
#define __CANIMATION_H__
#include <vector>
#include <string>
#include <set>
#include "../global.h"
/*
* CAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
struct SDL_Surface;
struct BMPPalette;
//class for def loading, methods are based on CDefHandler
//after loading will store general info (palette and frame offsets) and pointer to file itself
class CDefFile
{
private:
struct SSpriteDef
{
ui32 prSize;
ui32 defType2;
ui32 FullWidth;
ui32 FullHeight;
ui32 SpriteWidth;
ui32 SpriteHeight;
ui32 LeftMargin;
ui32 TopMargin;
};
unsigned char * data;
int datasize;
BMPPalette * colors;
//offset[group][frame] - offset of frame data in file
std::vector< std::vector <size_t> > offset;
//sorted list of offsets used to determine size
std::set <size_t> offList;
public:
CDefFile(std::string Name);
~CDefFile();
//true if file was opened correctly
bool loaded() const;
//get copy of palette to unpack compressed animation
BMPPalette * getPalette();
//true if frame is present in it
bool haveFrame(size_t frame, size_t group) const;
//get copy of binary data
unsigned char * getFrame(size_t frame, size_t group) const;
//load frame as SDL_Surface
SDL_Surface * loadFrame(size_t frame, size_t group) const ;
//static version of previous one for calling from compressed anim
static SDL_Surface * loadFrame(const unsigned char * FDef, const BMPPalette * palette);
};
// Class for handling animation.
class CAnimation
{
private:
//internal structure to hold all data of specific frame
struct AnimEntry
{
//surface for this entry
SDL_Surface * surf;
//bitfield, location of image data: 1 - def, 2 - file#9.*, 4 - file#9#2.*
unsigned char source;
//reference count, changed by loadFrame \ unloadFrame
size_t refCount;
//data for CompressedAnim
unsigned char * data;
//size of compressed data, unused for def files
size_t dataSize;
AnimEntry();
};
//animation file name
std::string name;
//if true all frames will be stored in compressed state
const bool compressed;
//palette from def file, used only for compressed anim
BMPPalette * defPalette;
//entries[group][position], store all info regarding frames
std::vector< std::vector <AnimEntry> > entries;
//loader, will be called by load(), require opened def file for loading from it. Returns true if image is loaded
bool loadFrame(CDefFile * file, size_t frame, size_t group);
//unloadFrame, returns true if image has been unloaded ( either deleted or decreased refCount)
bool unloadFrame(size_t frame, size_t group);
//decompress entry data
void decompress(AnimEntry &entry);
//initialize animation from file
void init(CDefFile * file);
//try to open def file
CDefFile * getFile() const;
//to get rid of copy-pasting error message :]
void printError(size_t frame, size_t group, std::string type) const;
public:
CAnimation(std::string Name, bool Compressed = false);
CAnimation();
~CAnimation();
//add custom surface to the end of specific group. If shared==true surface needs to be deleted
//somewhere outside of CAnim as well (SDL_Surface::refcount will be increased)
void add(SDL_Surface * surf, bool shared=false, size_t group=0);
//removes all surfaces which have compressed data
void purgeCompressed();
//get pointer to surface, this function ignores groups (like ourImages in DefHandler)
SDL_Surface * image (size_t frame);
//get pointer to surface, from specific group
SDL_Surface * image(size_t frame, size_t group);
//all available frames
void load ();
void unload();
//all frames from group
void loadGroup (size_t group);
void unloadGroup(size_t group);
//single image
void load (size_t frame, size_t group=0);
void unload(size_t frame, size_t group=0);
//list of frames (first = group ID, second = frame ID)
void load (std::vector <std::pair <size_t, size_t> > frames);
void unload(std::vector <std::pair <size_t, size_t> > frames);
//helper to fix frame order on some buttons
void fixButtonPos();
//size of specific group, 0 if not present
size_t groupSize(size_t group) const;
//total count of frames in whole anim
size_t size() const;
};
#endif // __CANIMATIONHANDLER_H__

View File

@ -119,6 +119,17 @@ unsigned char * CLodHandler::giveFile(std::string defName, int * length)
return NULL;
}
bool CLodHandler::haveFile(std::string name)
{
std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))toupper);
int dotPos = name.find_last_of('.');
if ( dotPos != -1 )
name.erase(dotPos);
Entry * ourEntry = entries.znajdz(Entry(name));
return ourEntry != NULL;
}
DLL_EXPORT int CLodHandler::infs2(unsigned char * in, int size, int realSize, unsigned char *& out, int wBits)
{
int ret;
@ -232,12 +243,15 @@ void CLodHandler::init(std::string lodFile, std::string dirName)
std::transform(entry.nameStr.begin(), entry.nameStr.end(),
entry.nameStr.begin(), toupper);
int dotPos = entry.nameStr.find_last_of('.');
std::string ext = entry.nameStr.substr(dotPos);
if (ext == ".MSK" || ext == ".MSG")
entry.nameStr[dotPos] = '#';//this files have same name as def - rename to defName#msk
else
entry.nameStr.erase(dotPos);//filename.ext becomes filename
size_t dotPos = entry.nameStr.find_last_of('.');
if ( dotPos < entry.nameStr.size() )
{
std::string ext = entry.nameStr.substr(dotPos);
if (ext == ".MSK" || ext == ".MSG")
entry.nameStr[dotPos] = '#';//this files have same name as def - rename to defName#msk
else
entry.nameStr.erase(dotPos);//filename.ext becomes filename
}
entry.offset= SDL_SwapLE32(lodEntries[i].offset);
entry.realSize = SDL_SwapLE32(lodEntries[i].uncompressedSize);
@ -259,12 +273,15 @@ void CLodHandler::init(std::string lodFile, std::string dirName)
std::string realname = name;
std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))toupper);
int dotPos = name.find_last_of('.');
std::string ext = name.substr(dotPos);
if (ext == ".MSK" || ext == ".MSG")
name[dotPos] = '#';//this files have same name as def - rename to defName#msk
else
name.erase(dotPos);//filename.ext becomes filename
size_t dotPos = name.find_last_of('.');
if ( dotPos < name.size() )
{
std::string ext = name.substr(dotPos);
if (ext == ".MSK" || ext == ".MSG")
name[dotPos] = '#';//this files have same name as def - rename to defName#msk
else
name.erase(dotPos);//filename.ext becomes filename
}
Entry * e = entries.znajdz(name);
if(e) //file present in .lod - overwrite its entry

View File

@ -77,6 +77,7 @@ public:
~CLodHandler();
int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler
unsigned char * giveFile(std::string defName, int * length=NULL); //returns pointer to the decompressed data - it must be deleted when no longer needed!
bool haveFile(std::string name);//check if file is present in lod
std::string getTextFile(std::string name); //extracts one file
void extractFile(std::string FName, std::string name); //extracts a specific file
void init(std::string lodFile, std::string dirName);

View File

@ -283,10 +283,10 @@ public:
}
template <typename T>
T* getVectorItemFromId(const VectorisedObjectInfo<T> &oInfo, si32 id) const
T* getVectorItemFromId(const VectorisedObjectInfo<T> &oInfo, ui32 id) const
{
if(id < 0)
return NULL;
/* if(id < 0)
return NULL;*/
assert(oInfo.vector);
assert(oInfo.vector->size() > id);
@ -673,14 +673,14 @@ public:
typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
if(const VectorisedObjectInfo<VType> *info = getVectorisedTypeInfo<VType>())
{
si32 id;
ui32 id;
*this >> id;
data = static_cast<T>(getVectorItemFromId(*info, id));
return;
}
}
ui32 pid = -1; //pointer id (or maybe rather pointee id)
ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
if(smartPointerSerialization)
{
*this >> pid; //get the id
@ -721,7 +721,7 @@ public:
template <typename T>
void ptrAllocated(const T *ptr, ui32 pid)
{
if(smartPointerSerialization && pid != -1)
if(smartPointerSerialization && pid != 0xffffffff)
loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
}