diff --git a/LunaDll/LuaMain/LuaProxy.h b/LunaDll/LuaMain/LuaProxy.h index ee3edf425..0df1374dd 100644 --- a/LunaDll/LuaMain/LuaProxy.h +++ b/LunaDll/LuaMain/LuaProxy.h @@ -830,7 +830,7 @@ namespace LuaProxy { void activateOverworldHud(WORLD_HUD_CONTROL activateFlag); //CSprite functions bool loadImage(const char* filename, int resNumber, int transColor); - luabind::object loadAnimatedImage(const std::string& filename, lua_State* L); + luabind::object loadAnimatedImage(const std::string& filename, int& smbxFrameTime, lua_State* L); LuaImageResource* loadImage(const char* filename); void placeSprite(int type, int imgResource, int xPos, int yPos, const char* extra, int time); void placeSprite(int type, int imgResource, int xPos, int yPos, const char* extra); diff --git a/LunaDll/LuaMain/LuaProxyComponent/LuaProxyGlobalFunctions/LuaProxyGlobalFuncGraphics.cpp b/LunaDll/LuaMain/LuaProxyComponent/LuaProxyGlobalFunctions/LuaProxyGlobalFuncGraphics.cpp index f2074e91f..ad20554ce 100644 --- a/LunaDll/LuaMain/LuaProxyComponent/LuaProxyGlobalFunctions/LuaProxyGlobalFuncGraphics.cpp +++ b/LunaDll/LuaMain/LuaProxyComponent/LuaProxyGlobalFunctions/LuaProxyGlobalFuncGraphics.cpp @@ -41,11 +41,11 @@ LuaProxy::Graphics::LuaImageResource* LuaProxy::Graphics::loadImage(const char* return new LuaProxy::Graphics::LuaImageResource(resNumber); } -luabind::object LuaProxy::Graphics::loadAnimatedImage(const std::string& filename, lua_State* L) +luabind::object LuaProxy::Graphics::loadAnimatedImage(const std::string& filename, int& smbxFrameTime, lua_State* L) { luabind::object tLuaImageResources = luabind::newtable(L); - std::vector resCodes = gLunaRender.LoadAnimatedBitmapResource(utf8_decode(filename)); - for (int i = 0; i < resCodes.size(); i++){ + std::vector resCodes = gLunaRender.LoadAnimatedBitmapResource(utf8_decode(filename), &smbxFrameTime); + for (unsigned int i = 0; i < resCodes.size(); i++){ tLuaImageResources[i + 1] = luabind::object(L, new LuaProxy::Graphics::LuaImageResource(resCodes[i]), luabind::adopt(luabind::result)); } return tLuaImageResources; diff --git a/LunaDll/LuaMain/LunaLuaMain.cpp b/LunaDll/LuaMain/LunaLuaMain.cpp index 37406331c..c485cf4c0 100644 --- a/LunaDll/LuaMain/LunaLuaMain.cpp +++ b/LunaDll/LuaMain/LunaLuaMain.cpp @@ -262,7 +262,7 @@ void CLunaLua::bindAll() class_("LuaImageResource"), def("loadImage", (bool(*)(const char*, int, int))&LuaProxy::Graphics::loadImage), def("loadImage", (LuaProxy::Graphics::LuaImageResource*(*)(const char*))&LuaProxy::Graphics::loadImage, adopt(result)), - def("loadAnimatedImage", &LuaProxy::Graphics::loadAnimatedImage), + def("loadAnimatedImage", &LuaProxy::Graphics::loadAnimatedImage, pure_out_value(_2)), def("placeSprite", (void(*)(int, int, int, int, const char*, int))&LuaProxy::Graphics::placeSprite), def("placeSprite", (void(*)(int, int, int, int, const char*))&LuaProxy::Graphics::placeSprite), def("placeSprite", (void(*)(int, int, int, int))&LuaProxy::Graphics::placeSprite), diff --git a/LunaDll/Rendering/RenderUtils.cpp b/LunaDll/Rendering/RenderUtils.cpp index ec47e77da..52c496a3b 100644 --- a/LunaDll/Rendering/RenderUtils.cpp +++ b/LunaDll/Rendering/RenderUtils.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "../Globals.h" #include "../GlobalFuncs.h" @@ -32,12 +33,13 @@ HBITMAP CreateEmptyBitmap(int width, int height, int bpp, void** data) return convHBMP; } -void LoadGfxAndEnumFrames(const std::wstring& filename, std::function bitmapEnumFunc){ +void LoadGfxAndEnumFrames(const std::wstring& filename, std::function bitmapEnumFunc){ HRESULT hr; IWICImagingFactory *pFactory = NULL; IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pFrame = NULL; IWICFormatConverter *pConvertedFrame = NULL; + IWICMetadataQueryReader* pMetadataReader = NULL; HBITMAP hDIBBitmap = NULL; unsigned int width = 0, height = 0; @@ -60,6 +62,9 @@ void LoadGfxAndEnumFrames(const std::wstring& filename, std::functionGetFrame(i, &pFrame); if (FAILED(hr)) goto cleanup; + + hr = pFrame->GetMetadataQueryReader(&pMetadataReader); + if (FAILED(hr)) goto cleanup; hr = pFactory->CreateFormatConverter(&pConvertedFrame); if (FAILED(hr)) goto cleanup; @@ -93,13 +98,29 @@ void LoadGfxAndEnumFrames(const std::wstring& filename, std::functionRelease(); + pMetadataReader = NULL; + } + if (pConvertedFrame) { + pConvertedFrame->Release(); + pConvertedFrame = NULL; + } + if (pFrame) { + pFrame->Release(); + pFrame = NULL; + } } cleanup: // NOTE: Not using CComPtr here because this should be possible to build with VS Express #pragma warning(suppress: 6102) + if (pMetadataReader) { + pMetadataReader->Release(); + } if (pConvertedFrame) { pConvertedFrame->Release(); } @@ -115,7 +136,7 @@ void LoadGfxAndEnumFrames(const std::wstring& filename, std::function LoadAnimatedGfx(const std::wstring& filename) +std::tuple, int> LoadAnimatedGfx(const std::wstring& filename) { std::vector allBitmapFrames; - LoadGfxAndEnumFrames(filename, [&allBitmapFrames](HBITMAP nextBitmap){ + int frameDelayQueries = 0; + short sumFrameDelay = 0; + LoadGfxAndEnumFrames(filename, [&allBitmapFrames, &frameDelayQueries, &sumFrameDelay](HBITMAP nextBitmap, IWICMetadataQueryReader* pMetadata){ allBitmapFrames.push_back(nextBitmap); + + _variant_t delayVal; + HRESULT hr = pMetadata->GetMetadataByName(L"/grctlext/Delay", (PROPVARIANT*)&delayVal); + if (SUCCEEDED(hr)) { + frameDelayQueries++; + sumFrameDelay += (short)delayVal; + } + return true; //continue enum }); - return allBitmapFrames; + + int frameTime = 0; + if (frameDelayQueries == 0) + { + frameTime = 9; + } + else + { + frameTime = sumFrameDelay / frameDelayQueries; + } + + return std::make_tuple(allBitmapFrames, frameTime); } diff --git a/LunaDll/Rendering/RenderUtils.h b/LunaDll/Rendering/RenderUtils.h index b85d66745..ea54931e9 100644 --- a/LunaDll/Rendering/RenderUtils.h +++ b/LunaDll/Rendering/RenderUtils.h @@ -4,9 +4,10 @@ #include #include #include +#include HBITMAP CreateEmptyBitmap(int width, int height, int bpp, void** data); HBITMAP LoadGfxAsBitmap(const std::wstring& filename); -std::vector LoadAnimatedGfx(const std::wstring& filename); +std::tuple, int> LoadAnimatedGfx(const std::wstring& filename); #endif \ No newline at end of file diff --git a/LunaDll/Rendering/Rendering.cpp b/LunaDll/Rendering/Rendering.cpp index 1fb04c5cc..26b07df14 100644 --- a/LunaDll/Rendering/Rendering.cpp +++ b/LunaDll/Rendering/Rendering.cpp @@ -11,7 +11,7 @@ #include "../SMBXInternal/PlayerMOB.h" #include "../GlobalFuncs.h" #include "GLEngine.h" - +#include using namespace std; @@ -88,7 +88,7 @@ bool Renderer::LoadBitmapResource(std::wstring filename, int resource_code) { } -std::vector Renderer::LoadAnimatedBitmapResource(std::wstring filename) +std::vector Renderer::LoadAnimatedBitmapResource(std::wstring filename, int* frameTime) { // Concoct full filepath wstring full_path = L""; @@ -107,9 +107,14 @@ std::vector Renderer::LoadAnimatedBitmapResource(std::wstring filename) full_path = filename; } - std::vector bitmaps = LoadAnimatedGfx(filename); + std::tuple, int> ret = LoadAnimatedGfx(filename); + std::vector& bitmaps = std::get<0>(ret); + if (frameTime) { + double avgFrameTime = (double)std::get<1>(ret); + *frameTime = (int)((avgFrameTime / 100) * 65); + } + std::vector bitmapResCode; - for (HBITMAP nextBitmap : bitmaps) { int nextResCode = GetAutoImageResourceCode(); BMPBox* pNewbox = new BMPBox(nextBitmap, m_hScreenDC); diff --git a/LunaDll/Rendering/Rendering.h b/LunaDll/Rendering/Rendering.h index 111a9aa36..54ce8fa6c 100644 --- a/LunaDll/Rendering/Rendering.h +++ b/LunaDll/Rendering/Rendering.h @@ -23,7 +23,7 @@ struct Renderer { bool LoadBitmapResource(std::wstring filename, int resource_code, int transparency_color); // don't give full path bool LoadBitmapResource(std::wstring filename, int resource_code); - std::vector LoadAnimatedBitmapResource(std::wstring filename); + std::vector LoadAnimatedBitmapResource(std::wstring filename, int* frameTime = 0); bool DeleteImage(int resource_code); int GetAutoImageResourceCode() const;