performance improvements
* no more freezes because of file IO from hard disk, now we cache sound/spr file buffers * more opengl painter tweaks
This commit is contained in:
parent
ee664657fb
commit
9aa12acc22
|
@ -28,6 +28,7 @@ FileStream::FileStream(const std::string& name, PHYSFS_File *fileHandle)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_fileHandle = fileHandle;
|
m_fileHandle = fileHandle;
|
||||||
|
m_cacheReadPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream::~FileStream()
|
FileStream::~FileStream()
|
||||||
|
@ -35,6 +36,24 @@ FileStream::~FileStream()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileStream::cache()
|
||||||
|
{
|
||||||
|
if(!m_fileHandle)
|
||||||
|
logTraceError("no file handle to cache");
|
||||||
|
|
||||||
|
// cache entire file into cache buffer
|
||||||
|
m_cacheReadPos = PHYSFS_tell(m_fileHandle);
|
||||||
|
PHYSFS_seek(m_fileHandle, 0);
|
||||||
|
int size = PHYSFS_fileLength(m_fileHandle);
|
||||||
|
m_cacheBuffer.resize(size);
|
||||||
|
int res = PHYSFS_read(m_fileHandle, &m_cacheBuffer[0], size, 1);
|
||||||
|
if(res == -1)
|
||||||
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
|
|
||||||
|
PHYSFS_close(m_fileHandle);
|
||||||
|
m_fileHandle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool FileStream::close()
|
bool FileStream::close()
|
||||||
{
|
{
|
||||||
if(m_fileHandle) {
|
if(m_fileHandle) {
|
||||||
|
@ -43,12 +62,18 @@ bool FileStream::close()
|
||||||
|
|
||||||
m_fileHandle = nullptr;
|
m_fileHandle = nullptr;
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
m_cacheBuffer.clear();
|
||||||
|
m_cacheReadPos = 0;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::flush()
|
bool FileStream::flush()
|
||||||
{
|
{
|
||||||
|
if(!m_fileHandle)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(PHYSFS_flush(m_fileHandle) == 0) {
|
if(PHYSFS_flush(m_fileHandle) == 0) {
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
return false;
|
return false;
|
||||||
|
@ -58,71 +83,143 @@ bool FileStream::flush()
|
||||||
|
|
||||||
int FileStream::read(void *buffer, int size, int nmemb)
|
int FileStream::read(void *buffer, int size, int nmemb)
|
||||||
{
|
{
|
||||||
|
if(m_fileHandle) {
|
||||||
int res = PHYSFS_read(m_fileHandle, buffer, size, nmemb);
|
int res = PHYSFS_read(m_fileHandle, buffer, size, nmemb);
|
||||||
if(res == -1) {
|
if(res == -1) {
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
} else {
|
||||||
|
uint maxReadPos = m_cacheBuffer.size()-1;
|
||||||
|
int writePos = 0;
|
||||||
|
uint8 *outBuffer = (uint8*)buffer;
|
||||||
|
for(int i=0;i<nmemb;++i) {
|
||||||
|
if(m_cacheReadPos+size > maxReadPos)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
for(int j=0;j<size;++j)
|
||||||
|
outBuffer[writePos++] = m_cacheBuffer[m_cacheReadPos++];
|
||||||
|
}
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::write(void *buffer, int count)
|
bool FileStream::write(void *buffer, int count)
|
||||||
{
|
{
|
||||||
|
if(!m_fileHandle)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(PHYSFS_write(m_fileHandle, buffer, 1, count) != count) {
|
if(PHYSFS_write(m_fileHandle, buffer, 1, count) != count) {
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::seek(int pos)
|
bool FileStream::seek(int pos)
|
||||||
{
|
{
|
||||||
|
if(m_fileHandle) {
|
||||||
if(PHYSFS_seek(m_fileHandle, pos) == 0) {
|
if(PHYSFS_seek(m_fileHandle, pos) == 0) {
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(pos > (int)m_cacheBuffer.size() || pos < 0) {
|
||||||
|
logTraceError("operation failed on '", m_name, "': seek pos cannot be greater than file length");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_cacheReadPos = pos;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileStream::size()
|
int FileStream::size()
|
||||||
{
|
{
|
||||||
|
if(m_fileHandle)
|
||||||
return PHYSFS_fileLength(m_fileHandle);
|
return PHYSFS_fileLength(m_fileHandle);
|
||||||
|
else
|
||||||
|
return m_cacheBuffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileStream::tell()
|
int FileStream::tell()
|
||||||
{
|
{
|
||||||
|
if(m_fileHandle)
|
||||||
return PHYSFS_tell(m_fileHandle);
|
return PHYSFS_tell(m_fileHandle);
|
||||||
|
else
|
||||||
|
return m_cacheReadPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 FileStream::getU8()
|
uint8 FileStream::getU8()
|
||||||
{
|
{
|
||||||
uint8 v = 0;
|
uint8 v = 0;
|
||||||
|
if(m_fileHandle) {
|
||||||
if(PHYSFS_read(m_fileHandle, &v, 1, 1) != 1)
|
if(PHYSFS_read(m_fileHandle, &v, 1, 1) != 1)
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
|
} else {
|
||||||
|
if(m_cacheReadPos+1 >= m_cacheBuffer.size()) {
|
||||||
|
logTraceError("operation failed on '", m_name, "': reached file eof");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = m_cacheBuffer[m_cacheReadPos];
|
||||||
|
m_cacheReadPos += 1;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 FileStream::getU16()
|
uint16 FileStream::getU16()
|
||||||
{
|
{
|
||||||
uint16 v = 0;
|
uint16 v = 0;
|
||||||
|
if(m_fileHandle) {
|
||||||
if(PHYSFS_readULE16(m_fileHandle, &v) == 0)
|
if(PHYSFS_readULE16(m_fileHandle, &v) == 0)
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
|
} else {
|
||||||
|
if(m_cacheReadPos+2 >= m_cacheBuffer.size()) {
|
||||||
|
logTraceError("operation failed on '", m_name, "': reached file eof");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = Fw::readLE16(&m_cacheBuffer[m_cacheReadPos]);
|
||||||
|
m_cacheReadPos += 2;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 FileStream::getU32()
|
uint32 FileStream::getU32()
|
||||||
{
|
{
|
||||||
uint32 v = 0;
|
uint32 v = 0;
|
||||||
|
if(m_fileHandle) {
|
||||||
if(PHYSFS_readULE32(m_fileHandle, &v) == 0)
|
if(PHYSFS_readULE32(m_fileHandle, &v) == 0)
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
|
} else {
|
||||||
|
if(m_cacheReadPos+4 >= m_cacheBuffer.size()) {
|
||||||
|
logTraceError("operation failed on '", m_name, "': reached file eof");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = Fw::readLE32(&m_cacheBuffer[m_cacheReadPos]);
|
||||||
|
m_cacheReadPos += 4;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FileStream::getU64()
|
uint64 FileStream::getU64()
|
||||||
{
|
{
|
||||||
uint64 v = 0;
|
uint64 v = 0;
|
||||||
|
if(m_fileHandle) {
|
||||||
if(PHYSFS_readULE64(m_fileHandle, (PHYSFS_uint64*)&v) == 0)
|
if(PHYSFS_readULE64(m_fileHandle, (PHYSFS_uint64*)&v) == 0)
|
||||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||||
|
} else {
|
||||||
|
if(m_cacheReadPos+8 >= m_cacheBuffer.size()) {
|
||||||
|
logTraceError("operation failed on '", m_name, "': reached file eof");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = Fw::readLE64(&m_cacheBuffer[m_cacheReadPos]);
|
||||||
|
m_cacheReadPos += 8;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
~FileStream();
|
~FileStream();
|
||||||
|
|
||||||
|
void cache();
|
||||||
bool close();
|
bool close();
|
||||||
bool flush();
|
bool flush();
|
||||||
bool write(void *buffer, int count);
|
bool write(void *buffer, int count);
|
||||||
|
@ -60,6 +61,9 @@ public:
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
PHYSFS_File *m_fileHandle;
|
PHYSFS_File *m_fileHandle;
|
||||||
|
|
||||||
|
std::vector<uint8_t> m_cacheBuffer;
|
||||||
|
uint m_cacheReadPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,7 +100,13 @@ void CoordsBuffer::updateCaches()
|
||||||
if(!m_hardwareCaching || m_hardwareCached)
|
if(!m_hardwareCaching || m_hardwareCached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_vertexArray.vertexCount() > 0) {
|
int vertexCount = m_vertexArray.vertexCount();
|
||||||
|
|
||||||
|
// there is only performance improvement when caching a lot of vertices
|
||||||
|
if(vertexCount < CACHE_MIN_VERTICES_COUNT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(vertexCount > 0) {
|
||||||
if(!m_hardwareVertexArray && m_vertexArray.vertexCount() > 0)
|
if(!m_hardwareVertexArray && m_vertexArray.vertexCount() > 0)
|
||||||
m_hardwareVertexArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
m_hardwareVertexArray = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||||
m_hardwareVertexArray->bind();
|
m_hardwareVertexArray->bind();
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
|
|
||||||
class CoordsBuffer
|
class CoordsBuffer
|
||||||
{
|
{
|
||||||
|
enum {
|
||||||
|
CACHE_MIN_VERTICES_COUNT = 48
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
CoordsBuffer();
|
CoordsBuffer();
|
||||||
~CoordsBuffer();
|
~CoordsBuffer();
|
||||||
|
|
|
@ -104,25 +104,27 @@ void Painter::setTexture(Texture* texture)
|
||||||
|
|
||||||
m_texture = texture;
|
m_texture = texture;
|
||||||
|
|
||||||
|
GLuint glTextureId;
|
||||||
if(texture) {
|
if(texture) {
|
||||||
setTextureMatrix(texture->getTransformMatrix());
|
setTextureMatrix(texture->getTransformMatrix());
|
||||||
|
glTextureId = texture->getId();
|
||||||
|
} else
|
||||||
|
glTextureId = 0;
|
||||||
|
|
||||||
GLuint glTextureId = texture->getId();
|
if(m_glTextureId != glTextureId) {
|
||||||
if(glTextureId != m_glTextureId) {
|
|
||||||
m_glTextureId = glTextureId;
|
m_glTextureId = glTextureId;
|
||||||
updateGlTexture();
|
updateGlTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Painter::updateGlTexture()
|
void Painter::updateGlTexture()
|
||||||
{
|
{
|
||||||
|
if(m_glTextureId != 0)
|
||||||
glBindTexture(GL_TEXTURE_2D, m_glTextureId);
|
glBindTexture(GL_TEXTURE_2D, m_glTextureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::updateGlCompositionMode()
|
void Painter::updateGlCompositionMode()
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
|
||||||
switch(m_compositionMode) {
|
switch(m_compositionMode) {
|
||||||
case CompositionMode_Normal:
|
case CompositionMode_Normal:
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
|
@ -62,7 +62,12 @@ void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
if(vertexCount == 0)
|
if(vertexCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool textured = coordsBuffer.getTextureCoordCount() != 0;
|
bool textured = coordsBuffer.getTextureCoordCount() != 0 && m_texture;
|
||||||
|
|
||||||
|
// skip drawing of empty textures
|
||||||
|
if(textured && m_texture->isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
if(textured != m_textureEnabled) {
|
if(textured != m_textureEnabled) {
|
||||||
if(textured)
|
if(textured)
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
@ -121,7 +126,7 @@ void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
|
|
||||||
void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||||
{
|
{
|
||||||
if(!texture->getId())
|
if(texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setTexture(texture.get());
|
setTexture(texture.get());
|
||||||
|
@ -130,7 +135,7 @@ void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr
|
||||||
|
|
||||||
void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setTexture(texture.get());
|
setTexture(texture.get());
|
||||||
|
@ -142,7 +147,7 @@ void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture,
|
||||||
|
|
||||||
void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setTexture(texture.get());
|
setTexture(texture.get());
|
||||||
|
|
|
@ -62,7 +62,11 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
if(vertexCount == 0)
|
if(vertexCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool textured = coordsBuffer.getTextureCoordCount() > 0;
|
bool textured = coordsBuffer.getTextureCoordCount() > 0 && m_texture;
|
||||||
|
|
||||||
|
// skip drawing of empty textures
|
||||||
|
if(textured && m_texture->isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
// update shader with the current painter state
|
// update shader with the current painter state
|
||||||
m_drawProgram->bind();
|
m_drawProgram->bind();
|
||||||
|
@ -100,7 +104,7 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||||
|
|
||||||
void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||||
{
|
{
|
||||||
if(!texture->getId())
|
if(texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
@ -110,7 +114,7 @@ void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr
|
||||||
|
|
||||||
void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
@ -123,7 +127,7 @@ void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture,
|
||||||
|
|
||||||
void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||||
|
|
|
@ -179,10 +179,12 @@ void Texture::generateSoftwareMipmaps(std::vector<uint8> inPixels)
|
||||||
|
|
||||||
Size inSize = getSize();
|
Size inSize = getSize();
|
||||||
Size outSize = inSize / 2;
|
Size outSize = inSize / 2;
|
||||||
std::vector<uint8> outPixels(outSize.area()*4);
|
std::vector<uint8> outPixels;
|
||||||
|
|
||||||
int mipmap = 1;
|
int mipmap = 1;
|
||||||
while(true) {
|
while(true) {
|
||||||
|
outPixels.resize(outSize.area()*4);
|
||||||
|
|
||||||
// this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel
|
// this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel
|
||||||
for(int x=0;x<outSize.width();++x) {
|
for(int x=0;x<outSize.width();++x) {
|
||||||
for(int y=0;y<outSize.height();++y) {
|
for(int y=0;y<outSize.height();++y) {
|
||||||
|
|
|
@ -60,6 +60,8 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
|
||||||
logError("unable to load texture '", fileName, "': ", e.what());
|
logError("unable to load texture '", fileName, "': ", e.what());
|
||||||
texture = g_graphics.getEmptyTexture();
|
texture = g_graphics.getEmptyTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(texture)
|
||||||
m_textures[filePath] = texture;
|
m_textures[filePath] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ SoundFilePtr SoundFile::loadSoundFile(const std::string& filename)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cache file buffer to avoid lags from hard drive
|
||||||
|
file->cache();
|
||||||
|
|
||||||
char magic[4];
|
char magic[4];
|
||||||
file->read(magic, 4);
|
file->read(magic, 4);
|
||||||
file->seek(0);
|
file->seek(0);
|
||||||
|
|
|
@ -41,6 +41,9 @@ bool SpriteManager::load(const std::string& file)
|
||||||
if(!m_spritesFile)
|
if(!m_spritesFile)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// cache file buffer to avoid lags from hard drive
|
||||||
|
m_spritesFile->cache();
|
||||||
|
|
||||||
m_signature = m_spritesFile->getU32();
|
m_signature = m_spritesFile->getU32();
|
||||||
m_spritesCount = m_spritesFile->getU16();
|
m_spritesCount = m_spritesFile->getU16();
|
||||||
m_sprites.resize(m_spritesCount);
|
m_sprites.resize(m_spritesCount);
|
||||||
|
|
Loading…
Reference in New Issue