Provide our own version of irrlicht's IGUISpriteBank, since theirs is too limited for our needs
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5346 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -77,6 +77,8 @@ supertuxkart_SOURCES = \
|
||||
graphics/water_splash.cpp \
|
||||
guiengine/CGUIFont.cpp \
|
||||
guiengine/CGUIFont.h \
|
||||
guiengine/CGUISpriteBank.cpp \
|
||||
guiengine/CGUISpriteBank.h \
|
||||
guiengine/abstract_state_manager.cpp \
|
||||
guiengine/abstract_state_manager.hpp \
|
||||
guiengine/engine.cpp \
|
||||
|
||||
284
src/guiengine/CGUISpriteBank.cpp
Normal file
284
src/guiengine/CGUISpriteBank.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
// 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>(Rectangles[n].getWidth()*m_scale,
|
||||
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>(dim.Width*m_scale, 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_
|
||||
|
||||
99
src/guiengine/CGUISpriteBank.h
Normal file
99
src/guiengine/CGUISpriteBank.h
Normal file
@@ -0,0 +1,99 @@
|
||||
// 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
|
||||
|
||||
#ifndef __C_GUI_MODIFIED_SPRITE_BANK_H_INCLUDED__
|
||||
#define __C_GUI_MODIFIED_SPRITE_BANK_H_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#ifdef _IRR_COMPILE_WITH_GUI_
|
||||
#include <cassert>
|
||||
#include "IGUISpriteBank.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
namespace video
|
||||
{
|
||||
class IVideoDriver;
|
||||
class ITexture;
|
||||
}
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class IGUIEnvironment;
|
||||
|
||||
//! Sprite bank interface.
|
||||
class STKModifiedSpriteBank : public IGUISpriteBank
|
||||
{
|
||||
public:
|
||||
|
||||
STKModifiedSpriteBank(IGUIEnvironment* env);
|
||||
virtual ~STKModifiedSpriteBank();
|
||||
|
||||
virtual core::array< core::rect<s32> >& getPositions();
|
||||
virtual core::array< SGUISprite >& getSprites();
|
||||
|
||||
virtual u32 getTextureCount() const;
|
||||
virtual video::ITexture* getTexture(u32 index) const;
|
||||
virtual void addTexture(video::ITexture* texture);
|
||||
virtual void setTexture(u32 index, video::ITexture* texture);
|
||||
|
||||
//! Add the texture and use it for a single non-animated sprite.
|
||||
virtual s32 addTextureAsSprite(video::ITexture* texture);
|
||||
|
||||
//! clears sprites, rectangles and textures
|
||||
virtual void clear();
|
||||
|
||||
//! Draws a sprite in 2d with position and color
|
||||
virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false);
|
||||
|
||||
//! Draws a sprite batch in 2d using an array of positions and a color
|
||||
virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos,
|
||||
const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0,
|
||||
bool loop=true, bool center=false);
|
||||
|
||||
void setScale(float scale)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// this object was getting access after being freed, I wanna see when/why
|
||||
unsigned int m_magic_number;
|
||||
|
||||
float m_scale;
|
||||
|
||||
struct SDrawBatch
|
||||
{
|
||||
core::array<core::position2di> positions;
|
||||
core::array<core::recti> sourceRects;
|
||||
u32 textureNumber;
|
||||
};
|
||||
|
||||
//FIXME: ugly hack to work around irrLicht limitations, see STKModifiedSpriteBank::getPositions()
|
||||
// for all the gory details.
|
||||
core::array< core::rect<s32> > copy;
|
||||
|
||||
core::array<SGUISprite> Sprites;
|
||||
core::array< core::rect<s32> > Rectangles;
|
||||
core::array<video::ITexture*> Textures;
|
||||
IGUIEnvironment* Environment;
|
||||
video::IVideoDriver* Driver;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_GUI_
|
||||
|
||||
#endif // __C_GUI_SPRITE_BANK_H_INCLUDED__
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
#include "guiengine/CGUISpriteBank.h"
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace irr::core;
|
||||
using namespace irr::gui;
|
||||
@@ -46,12 +48,12 @@ void ListWidget::add()
|
||||
//TODO: allow choosing which icons to use
|
||||
video::ITexture* icon = irr_driver->getTexture( file_manager->getGUIDir() + "/difficulty_medium.png" );
|
||||
|
||||
//FIXME: I have no clue what the parameter to 'addEmptySpriteBank' is for
|
||||
//FIXME: remember the created bank for future 'add's, since a bank must be created once only
|
||||
IGUISpriteBank* bank = GUIEngine::getGUIEnv()->addEmptySpriteBank( file_manager->getGUIDir().c_str() );
|
||||
// TODO: delete the bank when done using, it currently leaks
|
||||
STKModifiedSpriteBank* bank = new STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
|
||||
bank->setScale(0.5f);
|
||||
bank->addTextureAsSprite(icon);
|
||||
list->setSpriteBank(bank);
|
||||
list->setItemHeight( icon->getSize().Height );
|
||||
list->setItemHeight( icon->getSize().Height*0.5f );
|
||||
}
|
||||
|
||||
m_element = list;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
9507E9D10FC1CDCE00BD2B92 /* Ogg.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7F90FC1B63C00DB481B /* Ogg.framework */; };
|
||||
9507E9D20FC1CDCE00BD2B92 /* OpenAL.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FA0FC1B63C00DB481B /* OpenAL.framework */; };
|
||||
9507E9DB0FC1CDD500BD2B92 /* Vorbis.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FB0FC1B63C00DB481B /* Vorbis.framework */; };
|
||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */; };
|
||||
951B7D19108E52C900BC03AE /* challenges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951B7D18108E52C900BC03AE /* challenges.cpp */; };
|
||||
951BC65E0FFAF290006B5FF1 /* ipo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951BC65C0FFAF290006B5FF1 /* ipo.cpp */; };
|
||||
9522F125107948AD0067ECF5 /* main_menu_screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9522F124107948AD0067ECF5 /* main_menu_screen.cpp */; };
|
||||
@@ -306,6 +307,8 @@
|
||||
9505575F0F6968A50056E88C /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
|
||||
950557640F6968BE0056E88C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
|
||||
9507E9B60FC1CCE900BD2B92 /* stk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = stk.icns; sourceTree = SOURCE_ROOT; };
|
||||
950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGUISpriteBank.cpp; path = ../../guiengine/CGUISpriteBank.cpp; sourceTree = SOURCE_ROOT; };
|
||||
950D448B118DEE3C006CFC41 /* CGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGUISpriteBank.h; path = ../../guiengine/CGUISpriteBank.h; sourceTree = SOURCE_ROOT; };
|
||||
951B7D17108E52C900BC03AE /* challenges.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = challenges.hpp; path = ../../states_screens/challenges.hpp; sourceTree = SOURCE_ROOT; };
|
||||
951B7D18108E52C900BC03AE /* challenges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = challenges.cpp; path = ../../states_screens/challenges.cpp; sourceTree = SOURCE_ROOT; };
|
||||
951BC65C0FFAF290006B5FF1 /* ipo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ipo.cpp; path = ../../animations/ipo.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@@ -1220,6 +1223,8 @@
|
||||
children = (
|
||||
953C3CC910CAF3EE0025F78A /* CGUIFont.cpp */,
|
||||
953C3CCD10CAF4150025F78A /* CGUIFont.h */,
|
||||
950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */,
|
||||
950D448B118DEE3C006CFC41 /* CGUISpriteBank.h */,
|
||||
9583319810123B0200C5137E /* abstract_state_manager.cpp */,
|
||||
9583319710123B0200C5137E /* abstract_state_manager.hpp */,
|
||||
958330B210122B4A00C5137E /* engine.cpp */,
|
||||
@@ -2531,6 +2536,7 @@
|
||||
957ED4801163FF18002AB42C /* ai_base_controller.cpp in Sources */,
|
||||
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
|
||||
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */,
|
||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user