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
+ }