From 762c2ae5906001e16339d5f9510af32409a2e10d Mon Sep 17 00:00:00 2001 From: nastys <@> Date: Thu, 10 Oct 2019 00:49:15 +0200 Subject: [PATCH] Port twistero's DivaMovie from testing --- .../plugins/DivaMovie/DivaMovie.vcxproj | 1 + .../DivaMovie/DivaMovie.vcxproj.filters | 1 + .../plugins/DivaMovie/PluginConfigApi.h | 168 ++++++++++++++++++ .../source/plugins/DivaMovie/dllmain.cpp | 51 +++++- .../source/plugins/DivaMovie/framework.h | 26 ++- 5 files changed, 237 insertions(+), 10 deletions(-) create mode 100644 source-code/source/plugins/DivaMovie/PluginConfigApi.h diff --git a/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj b/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj index 35db075..81afc1e 100644 --- a/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj +++ b/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj @@ -85,6 +85,7 @@ + diff --git a/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj.filters b/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj.filters index d746774..ce68d0f 100644 --- a/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj.filters +++ b/source-code/source/plugins/DivaMovie/DivaMovie.vcxproj.filters @@ -5,5 +5,6 @@ + \ No newline at end of file diff --git a/source-code/source/plugins/DivaMovie/PluginConfigApi.h b/source-code/source/plugins/DivaMovie/PluginConfigApi.h new file mode 100644 index 0000000..d0ffd94 --- /dev/null +++ b/source-code/source/plugins/DivaMovie/PluginConfigApi.h @@ -0,0 +1,168 @@ +#pragma once +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include + +// resolution class to store and sort the width and height easily +class resolution +{ +public: + unsigned int width; + unsigned int height; + + resolution() + { + width = 0; + height = 0; + } + + resolution(unsigned int width, unsigned int height) + { + resolution::width = width; + resolution::height = height; + } + + bool operator ==(const resolution &res2) + { + return width == res2.width && height == res2.height; + } + + // in comparisons width takes priority because it's usually displayed first + bool operator <(const resolution &res2) + { + if (width == res2.width) + return height < res2.height; + else + return width < res2.width; + } + bool operator >(const resolution &res2) + { + if (width == res2.width) + return height > res2.height; + else + return width > res2.width; + } +}; + +namespace PluginConfig +{ +#pragma pack(push, 1) + enum ConfigType { + CONFIG_BOOLEAN, + CONFIG_NUMERIC, + CONFIG_STRING, + CONFIG_DROPDOWN_INDEX, + CONFIG_DROPDOWN_TEXT, + CONFIG_DROPDOWN_NUMBER, + CONFIG_RESOLUTION, + CONFIG_GROUP_START, + CONFIG_GROUP_END, + CONFIG_BUTTON, + CONFIG_SPACER + }; + + struct PluginConfigBooleanData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + bool defaultVal; + bool saveAsString; + }; + + struct PluginConfigNumericData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + int defaultVal; + int minVal; + int maxVal; + }; + + struct PluginConfigStringData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + LPCWSTR defaultVal; + bool useUtf8; + }; + + struct PluginConfigDropdownIndexData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + int defaultVal; + std::vector valueStrings; + }; + + struct PluginConfigDropdownTextData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + LPCWSTR defaultVal; + std::vector valueStrings; + bool editable; + bool useUtf8; + }; + + struct PluginConfigDropdownNumberData { + LPCWSTR iniVarName; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + int defaultVal; + std::vector valueInts; + bool editable; + }; + + struct PluginConfigResolutionData { + LPCWSTR iniVarName; + LPCWSTR iniVarName2; + LPCWSTR iniSectionName; + LPCWSTR iniFilePath; + LPCWSTR friendlyName; + LPCWSTR description; + resolution defaultVal; + std::vector valueResolutions; + bool editable; + }; + + struct PluginConfigGroupData + { + LPCWSTR name; + int height; + }; + + struct PluginConfigButtonData { + LPCWSTR friendlyName; + LPCWSTR description; + void(*func)(); + }; + + struct PluginConfigSpacerData { + int height; + }; + + struct PluginConfigOption + { + ConfigType cfgType; + void* data; + }; + + struct PluginConfigArray + { + int len; + PluginConfigOption* options; + }; +#pragma pack(pop) +} \ No newline at end of file diff --git a/source-code/source/plugins/DivaMovie/dllmain.cpp b/source-code/source/plugins/DivaMovie/dllmain.cpp index ccfa5f9..3258ae5 100644 --- a/source-code/source/plugins/DivaMovie/dllmain.cpp +++ b/source-code/source/plugins/DivaMovie/dllmain.cpp @@ -1,4 +1,5 @@ #include "framework.h" +#include "PluginConfigApi.h" #include @@ -10,6 +11,8 @@ #include #include +bool forceSoftwareDecoding; + IDirect3DDeviceManager9* deviceManager; IMFTransform* mfTransform; @@ -124,14 +127,28 @@ end: VTABLE_HOOK(HRESULT, IMFTransform, ProcessMessage, MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) { - HRESULT result = originalProcessMessage(This, eMessage, ulParam); - if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE) + if (forceSoftwareDecoding) { - result = originalProcessMessage(This, eMessage, NULL); - if (SUCCEEDED(result)) + if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER) { + PRINT("[DivaMovie] Force Software Decoding enabled\n"); INSTALL_VTABLE_HOOK(This, ProcessOutput, 25); + return S_OK; + } + return originalProcessMessage(This, eMessage, ulParam); } - return result; + else + { + HRESULT result = originalProcessMessage(This, eMessage, ulParam); + if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE) + { + PRINT("[DivaMovie] This system does not support DXVA hardware decoding\n"); + result = originalProcessMessage(This, eMessage, NULL); + if (SUCCEEDED(result)) + INSTALL_VTABLE_HOOK(This, ProcessOutput, 25); + } + return result; + } + } HOOK(void*, IMFTransformInitializer, 0x140420B90, void* a1, void* a2, IMFTransform** transform) @@ -158,13 +175,37 @@ HOOK(HRESULT, DXVA2CreateDirect3DDeviceManager, PROC_ADDRESS("dxva2.dll", "DXVA2 return result; } +void loadConfig() { + forceSoftwareDecoding = GetPrivateProfileIntW(L"general", L"force_software_decoding", 0, CONFIG_FILE) > 0 ? true : false; +} + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { + loadConfig(); INSTALL_HOOK(DXVA2CreateDirect3DDeviceManager); INSTALL_HOOK(IMFTransformInitializer); } return TRUE; +} + +PluginConfig::PluginConfigOption config[] = { + { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"force_software_decoding", L"general", CONFIG_FILE, L"Force Software Decoding", L"Use software decoding even on systems that support DXVA hardware decoding.", false } }, +}; + +extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) +{ + return L"DivaMovie"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) +{ + return L"DivaMovie Plugin by Skyth\n\nDivaMovie enables movies on systems that does not support DXVA hardware decoding."; +} + +extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void) +{ + return PluginConfig::PluginConfigArray{ _countof(config), config }; } \ No newline at end of file diff --git a/source-code/source/plugins/DivaMovie/framework.h b/source-code/source/plugins/DivaMovie/framework.h index 08002d0..aadfe46 100644 --- a/source-code/source/plugins/DivaMovie/framework.h +++ b/source-code/source/plugins/DivaMovie/framework.h @@ -5,12 +5,28 @@ #include #include #include +#include -#if _DEBUG +std::wstring ExePath() { + WCHAR buffer[MAX_PATH]; + GetModuleFileNameW(NULL, buffer, MAX_PATH); + return std::wstring(buffer); +} + +std::wstring DirPath() { + std::wstring exepath = ExePath(); + std::wstring::size_type pos = exepath.find_last_of(L"\\/"); + return exepath.substr(0, pos); +} + +std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DivaMovie.ini"; +LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str(); + +//#if _DEBUG #define PRINT(value, ...) printf(value, __VA_ARGS__); -#else -#define PRINT(value, ...) -#endif +//#else +//#define PRINT(value, ...) +//#endif #define PROC_ADDRESS(libraryName, procName) \ GetProcAddress(LoadLibrary(TEXT(libraryName)), procName) @@ -59,4 +75,4 @@ else \ { \ PRINT("[DivaMovie] %s succeeded\n", #function); \ - } \ No newline at end of file + }