diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp index a5e88acb..05282493 100644 --- a/src/client/luafunctions.cpp +++ b/src/client/luafunctions.cpp @@ -94,6 +94,7 @@ void Client::registerLuaFunctions() g_lua.registerSingletonClass("g_sprites"); g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites); + g_lua.bindSingletonFunction("g_sprites", "saveSpr", &SpriteManager::saveSpr, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "isLoaded", &SpriteManager::isLoaded, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "getSprSignature", &SpriteManager::getSignature, &g_sprites); diff --git a/src/client/spritemanager.cpp b/src/client/spritemanager.cpp index fa2e9ab2..001370aa 100644 --- a/src/client/spritemanager.cpp +++ b/src/client/spritemanager.cpp @@ -63,6 +63,60 @@ bool SpriteManager::loadSpr(std::string file) } } +void SpriteManager::saveSpr(std::string fileName) +{ + if(!m_loaded) + stdext::throw_exception("failed to save, spr is not loaded"); + + try { + FileStreamPtr fin = g_resources.createFile(fileName); + if(!fin) + stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName)); + + fin->cache(); + + fin->addU32(m_signature); + if(g_game.getFeature(Otc::GameSpritesU32)) + fin->addU32(m_spritesCount); + else + fin->addU16(m_spritesCount); + + uint32 offset = fin->tell(); + uint32 spriteAddress = offset + 4 * m_spritesCount; + for(int i = 1; i <= m_spritesCount; i++) + fin->addU32(0); + + for(int i = 1; i <= m_spritesCount; i++) { + m_spritesFile->seek((i - 1) * 4 + m_spritesOffset); + uint32 fromAdress = m_spritesFile->getU32(); + if(fromAdress != 0) { + fin->seek(offset + (i - 1) * 4); + fin->addU32(spriteAddress); + fin->seek(spriteAddress); + + m_spritesFile->seek(fromAdress); + fin->addU8(m_spritesFile->getU8()); + fin->addU8(m_spritesFile->getU8()); + fin->addU8(m_spritesFile->getU8()); + + uint16 dataSize = m_spritesFile->getU16(); + char spriteData[dataSize]; + fin->addU16(dataSize); + m_spritesFile->read(spriteData, dataSize); + fin->write(spriteData, dataSize); + + spriteAddress = fin->tell(); + } + //TODO: Check for overwritten sprites. + } + + fin->flush(); + fin->close(); + } catch(std::exception& e) { + g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); + } +} + void SpriteManager::unload() { m_spritesCount = 0; diff --git a/src/client/spritemanager.h b/src/client/spritemanager.h index cd074f4f..893bc34b 100644 --- a/src/client/spritemanager.h +++ b/src/client/spritemanager.h @@ -37,6 +37,8 @@ public: bool loadSpr(std::string file); void unload(); + void saveSpr(std::string fileName); + uint32 getSignature() { return m_signature; } int getSpritesCount() { return m_spritesCount; }