03c6500265
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5697 178a84e3-b1eb-0310-8ba1-8eac791a3b58
286 lines
7.7 KiB
C++
286 lines
7.7 KiB
C++
// Copyright (C) 2002-2009 Nikolaus Gebhardt, modified by Marianne Gagnon
|
|
// This file is part of the "Irrlicht Engine".
|
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
|
|
|
#include "guiengine/CGUISpriteBank.h"
|
|
#ifdef _IRR_COMPILE_WITH_GUI_
|
|
|
|
#include "IGUIEnvironment.h"
|
|
#include "IVideoDriver.h"
|
|
#include "ITexture.h"
|
|
#include <cassert>
|
|
|
|
namespace irr
|
|
{
|
|
namespace gui
|
|
{
|
|
|
|
STKModifiedSpriteBank::STKModifiedSpriteBank(IGUIEnvironment* env) :
|
|
Environment(env), Driver(0)
|
|
{
|
|
m_magic_number = 0xCAFEC001;
|
|
|
|
#ifdef _DEBUG
|
|
setDebugName("STKModifiedSpriteBank");
|
|
#endif
|
|
|
|
m_scale = 1.0f;
|
|
|
|
if (Environment)
|
|
{
|
|
Driver = Environment->getVideoDriver();
|
|
if (Driver)
|
|
Driver->grab();
|
|
}
|
|
}
|
|
|
|
|
|
STKModifiedSpriteBank::~STKModifiedSpriteBank()
|
|
{
|
|
// drop textures
|
|
for (u32 i=0; i<Textures.size(); ++i)
|
|
if (Textures[i])
|
|
Textures[i]->drop();
|
|
|
|
// drop video driver
|
|
if (Driver)
|
|
Driver->drop();
|
|
|
|
m_magic_number = 0xDEADBEEF;
|
|
}
|
|
|
|
|
|
core::array< core::rect<s32> >& STKModifiedSpriteBank::getPositions()
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
copy.clear();
|
|
|
|
//FIXME: terribly unefficient, CGUIListBox will call this once for every item xD
|
|
// but I have no choice, short of re-implementing IGUIListBox too
|
|
|
|
for (int n=0; n<(int)Rectangles.size(); n++)
|
|
{
|
|
copy.push_back(
|
|
core::rect<s32>(Rectangles[n].UpperLeftCorner,
|
|
core::dimension2d<s32>((int)(Rectangles[n].getWidth()*m_scale),
|
|
(int)(Rectangles[n].getHeight()*m_scale)) )
|
|
);
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
|
|
core::array< SGUISprite >& STKModifiedSpriteBank::getSprites()
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
return Sprites;
|
|
}
|
|
|
|
|
|
u32 STKModifiedSpriteBank::getTextureCount() const
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
return Textures.size();
|
|
}
|
|
|
|
|
|
video::ITexture* STKModifiedSpriteBank::getTexture(u32 index) const
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
if (index < Textures.size())
|
|
return Textures[index];
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
|
|
void STKModifiedSpriteBank::addTexture(video::ITexture* texture)
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
if (texture)
|
|
texture->grab();
|
|
|
|
Textures.push_back(texture);
|
|
}
|
|
|
|
|
|
void STKModifiedSpriteBank::setTexture(u32 index, video::ITexture* texture)
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
while (index >= Textures.size())
|
|
Textures.push_back(0);
|
|
|
|
if (texture)
|
|
texture->grab();
|
|
|
|
if (Textures[index])
|
|
Textures[index]->drop();
|
|
|
|
Textures[index] = texture;
|
|
}
|
|
|
|
|
|
//! clear everything
|
|
void STKModifiedSpriteBank::clear()
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
// drop textures
|
|
for (u32 i=0; i<Textures.size(); ++i)
|
|
if (Textures[i])
|
|
Textures[i]->drop();
|
|
Textures.clear();
|
|
Sprites.clear();
|
|
Rectangles.clear();
|
|
}
|
|
|
|
//! Add the texture and use it for a single non-animated sprite.
|
|
s32 STKModifiedSpriteBank::addTextureAsSprite(video::ITexture* texture)
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
if ( !texture )
|
|
return -1;
|
|
|
|
addTexture(texture);
|
|
u32 textureIndex = getTextureCount() - 1;
|
|
|
|
u32 rectangleIndex = Rectangles.size();
|
|
Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
|
|
|
|
SGUISprite sprite;
|
|
sprite.frameTime = 0;
|
|
|
|
SGUISpriteFrame frame;
|
|
frame.textureNumber = textureIndex;
|
|
frame.rectNumber = rectangleIndex;
|
|
sprite.Frames.push_back( frame );
|
|
|
|
Sprites.push_back( sprite );
|
|
|
|
return Sprites.size() - 1;
|
|
}
|
|
|
|
//! draws a sprite in 2d with scale and color
|
|
void STKModifiedSpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
|
|
const core::rect<s32>* clip, const video::SColor& color,
|
|
u32 starttime, u32 currenttime, bool loop, bool center)
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
|
return;
|
|
|
|
// work out frame number
|
|
u32 frame = 0;
|
|
if (Sprites[index].frameTime)
|
|
{
|
|
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
|
if (loop)
|
|
frame = f % Sprites[index].Frames.size();
|
|
else
|
|
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
|
}
|
|
|
|
const video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber];
|
|
if (!tex)
|
|
return;
|
|
|
|
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
|
if (rn >= Rectangles.size())
|
|
return;
|
|
|
|
const core::rect<s32>& r = Rectangles[rn];
|
|
|
|
const core::dimension2d<s32>& dim = r.getSize();
|
|
|
|
core::rect<s32> dest( pos, core::dimension2d<s32>((int)(dim.Width*m_scale),
|
|
(int)(dim.Height*m_scale)) );
|
|
if (center)
|
|
{
|
|
dest -= dest.getSize() / 2;
|
|
}
|
|
|
|
/*
|
|
draw2DImage (const video::ITexture *texture, const core::rect< s32 > &destRect,
|
|
const core::rect< s32 > &sourceRect, const core::rect< s32 > *clipRect=0,
|
|
const video::SColor *const colors=0, bool useAlphaChannelOfTexture=false)=0
|
|
*/
|
|
Driver->draw2DImage(tex, dest, r /* source rect */, clip, NULL /* colors */, true);
|
|
|
|
}
|
|
|
|
|
|
void STKModifiedSpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
|
|
const core::array<core::position2di>& pos,
|
|
const core::rect<s32>* clip,
|
|
const video::SColor& color,
|
|
u32 starttime, u32 currenttime,
|
|
bool loop, bool center)
|
|
{
|
|
assert( m_magic_number == 0xCAFEC001 );
|
|
const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
|
|
|
|
core::array<SDrawBatch> drawBatches(Textures.size());
|
|
for(u32 i = 0;i < Textures.size();i++)
|
|
{
|
|
drawBatches.push_back(SDrawBatch());
|
|
drawBatches[i].positions.reallocate(drawCount);
|
|
drawBatches[i].sourceRects.reallocate(drawCount);
|
|
}
|
|
|
|
for(u32 i = 0;i < drawCount;i++)
|
|
{
|
|
const u32 index = indices[i];
|
|
|
|
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
|
continue;
|
|
|
|
// work out frame number
|
|
u32 frame = 0;
|
|
if (Sprites[index].frameTime)
|
|
{
|
|
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
|
if (loop)
|
|
frame = f % Sprites[index].Frames.size();
|
|
else
|
|
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
|
}
|
|
|
|
const u32 texNum = Sprites[index].Frames[frame].textureNumber;
|
|
|
|
SDrawBatch& currentBatch = drawBatches[texNum];
|
|
|
|
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
|
if (rn >= Rectangles.size())
|
|
return;
|
|
|
|
const core::rect<s32>& r = Rectangles[rn];
|
|
|
|
if (center)
|
|
{
|
|
core::position2di p = pos[i];
|
|
p -= r.getSize() / 2;
|
|
|
|
currentBatch.positions.push_back(p);
|
|
currentBatch.sourceRects.push_back(r);
|
|
}
|
|
else
|
|
{
|
|
currentBatch.positions.push_back(pos[i]);
|
|
currentBatch.sourceRects.push_back(r);
|
|
}
|
|
}
|
|
|
|
for(u32 i = 0;i < drawBatches.size();i++)
|
|
{
|
|
if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
|
|
Driver->draw2DImageBatch(Textures[i], drawBatches[i].positions,
|
|
drawBatches[i].sourceRects, clip, color, true);
|
|
}
|
|
}
|
|
|
|
} // namespace gui
|
|
} // namespace irr
|
|
|
|
#endif // _IRR_COMPILE_WITH_GUI_
|
|
|